代码之家  ›  专栏  ›  技术社区  ›  Chris Holmes

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

  •  2
  • Chris Holmes  · 技术社区  · 14 年前

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

    2 回复  |  直到 14 年前
        1
  •  1
  •   Scott    14 年前

    如果您正在清除数据,那么您似乎只是在替换所有数据,然后一次添加一个数据项。不必重复使用ObservaleCollection,您可以简单地将数据网格的itemssource设置为带有新项的新ObservaleCollection吗?

        2
  •  2
  •   JanW    14 年前

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

    当您处于编辑模式时,my collection类阻止集合更改事件。在清除项目之前启动“BeginEdit”。然后添加新项目。完成后,使用“committedit”,视图将只刷新一次。

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

    从list.BeginEdit()中删除//并查看区别。大约15秒后<1秒钟。

    问候语,