更新WPF中的ObservableCollection会导致屏幕闪烁;我怎样才能预防它?
我有一个以MVVM模式绑定到WPFToolkit数据网格的ObservableCollection。每隔30秒,我就会有一个后台线程查询服务中的一些数据。当它返回时,它将其封送到UI线程并更新ObservableCollection,方法是首先对集合调用Clear(),然后对每个项调用Add()。发生这种情况时,数据会正确地更新到屏幕上,但是,datagrid会闪烁。我怎样才能防止这种情况发生 我为您的问题创建了一个简单但功能最大的解决方案:更新WPF中的ObservableCollection会导致屏幕闪烁;我怎样才能预防它?,wpf,datagrid,wpftoolkit,observablecollection,flicker,Wpf,Datagrid,Wpftoolkit,Observablecollection,Flicker,我有一个以MVVM模式绑定到WPFToolkit数据网格的ObservableCollection。每隔30秒,我就会有一个后台线程查询服务中的一些数据。当它返回时,它将其封送到UI线程并更新ObservableCollection,方法是首先对集合调用Clear(),然后对每个项调用Add()。发生这种情况时,数据会正确地更新到屏幕上,但是,datagrid会闪烁。我怎样才能防止这种情况发生 我为您的问题创建了一个简单但功能最大的解决方案: public class MyCollection&
public class MyCollection<T> : ObservableCollection<T>
{
private bool _isInEditMode = false;
public void BeginEdit()
{
_isInEditMode = true;
}
public void CommitEdit()
{
_isInEditMode = false;
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (_isInEditMode == false)
{
base.OnCollectionChanged(e);
}
}
}
公共类MyCollection:ObservableCollection
{
私有bool _isInEditMode=false;
public void BeginEdit()
{
_isInEditMode=true;
}
公共承诺
{
_isInEditMode=false;
OnCollectionChanged(新建NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
CollectionChanged上的受保护覆盖无效(NotifyCollectionChangedEventArgs e)
{
如果(_isInEditMode==false)
{
基础。变更的集合(e);
}
}
}
“我的收藏”类防止在编辑模式下发生收藏更改事件。在清除项目之前启动“BeginEdit”。然后添加新项目。完成后,使用“CommittedIt”,视图将只刷新一次
如果我用一个简单的列表框测试了它,我在其中添加了1.000.000个字符串项。试试这个。很有趣:)
private void按钮\u单击(对象发送者,路由目标)
{
MyCollection list=testBox.ItemsSource作为MyCollection;
//list.BeginEdit();
对于(int i=0;i<1000000;i++)
{
列表。添加(“测试”+i);
}
list.committedit();
}
从list.BeginEdit()中删除//并查看差异。大约15秒,小于1秒
您好
Jan如果您正在清除数据,那么您似乎只是在替换所有数据,然后一次添加一个数据项。与其重复使用ObservableCollection,不如简单地将数据网格的itemssource设置为一个新的ObservableCollection和新的items?就是这样。我认为重复使用收藏是避免闪烁的正确方法,但事实证明,你的建议是正确的方法!谢谢没问题。我相信闪烁是在你清除可观察到的采集时引起的。。。因此,DataGrid从充满旧数据变为空(闪烁),然后在添加新项目时重新填充。现在,您只需从填充旧数据,到填充新数据。。。中间没有空状态。我讨厌我用来避免问题的技术是导致问题的技术。抱歉,Jan,这没有解决问题。闪烁的光还在那里。幸运的是,每次只需绑定到一个新集合就可以解决这个问题。啊,好吧,很遗憾它不适用于数据网格。没有测试它。与其他项控件一起使用,效果非常好。如果您总是替换整个列表,那么使用新列表的解决方案肯定要简单得多。我创建了一个类似于observable集合的扩展,以添加一个AddRange方法,就像其他集合一样。我从来没有注意到它的闪烁,但我只是添加了一批项目,从来没有做过完全清除。。。
private void Button_Click(object sender, RoutedEventArgs e)
{
MyCollection<string> list = testBox.ItemsSource as MyCollection<string>;
//list.BeginEdit();
for (int i = 0; i < 1000000; i++)
{
list.Add("test " + i);
}
list.CommitEdit();
}