[英]How to update ItemsSource without ObservableCollection
[英]How to Update ComboBox ItemsSource Without Flickering
我正在努力对以前可以使用的ComboBox
进行更新。 我最初将其ItemsSource
绑定到ViewModel中的只读ObservableCollection<char>
属性。 当用户发起更改时(通过鼠标笔划完成更改,在某些情况下,每秒执行数十次),get会从Model重建集合并返回它。
当我在ObservableCollection
更改为自己的对象时, ComboBox
在更新期间开始闪烁。 我不知道怎么了。 这是从XAML开始的有效代码:
<ComboBox ItemsSource='{Binding FromBins}' SelectedValue='{Binding SelectedFromBin, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}' />
视图模型:
public ObservableCollection<char> FromBins
{
get
{
ObservableCollection<char> tempBins = new ObservableCollection<char>();
foreach (var item in Map.BinCounts)
{
tempBins.Add(item.Key);
}
return tempBins;
}
}
我只是在每次鼠标移动时都进行了属性更改,并且界面按预期工作(存在其他逻辑来确保SelectedItem
有效)。
为了使界面更有用,我决定使用自己的类向ComboBox
添加更多信息:
public class BinItem : IEquatable<BinItem>
{
public char Bin { get; set; }
public SolidColorBrush BinColor { get; set; }
public string BinColorToolTip { get {...} }
public BinItem( char bin )
{
Bin = bin;
BinColor = new SolidColorBrush(BinColors.GetBinColor(bin));
}
public bool Equals(BinItem other)
{
return other.Bin == Bin ? true : false;
}
}
如果我在工作代码ViewModel BinItem
char
换为BinItem
,则在移动鼠标时会闪烁。 这是更新的XAML:
<ComboBox ItemsSource='{Binding FromBins}' SelectedValue='{Binding SelectedFromBin, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}'>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" ToolTip='{Binding BinColorToolTip}'>
<Rectangle Fill='{Binding BinColor}' Width='10' Height='10' HorizontalAlignment='Center' VerticalAlignment='Center' Margin='0,0,4,0' Stroke='#FF747474' />
<TextBlock Text="{Binding Bin}" Width='16' />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
我已经尝试了很多方法,包括但不限于:-使用List
而不是ObservableCollection
但是即使Get
每次都触发并返回正确的项目集合,接口也不会总是更新(尽管闪烁消失了)。 -将所有可能的垃圾箱留在项源中,并将Visibility
属性添加到绑定到的BinItem类中(无法更新)。
我怀疑我做的事情根本上是错误的,但是到目前为止,搜索SO或其他方式均无济于事。 任何帮助表示赞赏。
我能够使用Clemens和Chris的想法解决这个问题。 不确定这是否是最优雅的解决方案,但它是否按预期工作,而性能却没有明显下降。
我没有通过每次刷新替换集合的方法,而是通过逻辑来找出更改的内容(每次更新都可以同时添加和删除)。 代码如下:
private ObservableCollection<BinItem> _FromBins = new ObservableCollection<BinItem>();
public ObservableCollection<BinItem> FromBins
{
get
{
if (_FromBins.Count > 0)
{
List<char> BinsToRemove = new List<char>();
foreach (var item in _FromBins)
{
if (!Map.BinCounts.ContainsKey(item.Bin))
{
BinsToRemove.Add(item.Bin);
}
}
foreach (var item in BinsToRemove)
{
_FromBins.Remove(new BinItem(item));
}
}
foreach (var item in Map.BinCounts)
{
if (!_FromBins.Contains(new BinItem(item.Key)) && item.Value > 0) {
_FromBins.Add(new BinItem(item.Key));
}
}
return _FromBins;
}
}
希望这也可以帮助其他人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.