Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
更新WPF中的ObservableCollection会导致屏幕闪烁;我怎样才能预防它?_Wpf_Datagrid_Wpftoolkit_Observablecollection_Flicker - Fatal编程技术网

更新WPF中的ObservableCollection会导致屏幕闪烁;我怎样才能预防它?

更新WPF中的ObservableCollection会导致屏幕闪烁;我怎样才能预防它?,wpf,datagrid,wpftoolkit,observablecollection,flicker,Wpf,Datagrid,Wpftoolkit,Observablecollection,Flicker,我有一个以MVVM模式绑定到WPFToolkit数据网格的ObservableCollection。每隔30秒,我就会有一个后台线程查询服务中的一些数据。当它返回时,它将其封送到UI线程并更新ObservableCollection,方法是首先对集合调用Clear(),然后对每个项调用Add()。发生这种情况时,数据会正确地更新到屏幕上,但是,datagrid会闪烁。我怎样才能防止这种情况发生 我为您的问题创建了一个简单但功能最大的解决方案: public class MyCollection&

我有一个以MVVM模式绑定到WPFToolkit数据网格的ObservableCollection。每隔30秒,我就会有一个后台线程查询服务中的一些数据。当它返回时,它将其封送到UI线程并更新ObservableCollection,方法是首先对集合调用Clear(),然后对每个项调用Add()。发生这种情况时,数据会正确地更新到屏幕上,但是,datagrid会闪烁。我怎样才能防止这种情况发生

我为您的问题创建了一个简单但功能最大的解决方案:

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();

    }