【问题标题】:Pause the Updates to DataGrid of bound ObservableCollection<T>暂停对绑定 ObservableCollection<T> 的 DataGrid 的更新
【发布时间】:2011-07-26 08:06:09
【问题描述】:

有没有办法暂停ObservableCollectionNotifyCollectionChanged 事件?我的想法如下:

public class PausibleObservableCollection<Message> : ObservableCollection<Message>
{
    public bool IsBindingPaused { get; set; }

    protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        if (!IsBindingPaused)
            base.OnCollectionChanged(e);
    }
}

这确实暂停了通知,但显然当时被遗漏(但仍添加)的项目在 NotifyCollectionChangedEventArgs 内,因此当我再次启用通知时不会传递给绑定的 DataGrid。

我是否必须想出一个集合的自定义实现来控制这个方面?

【问题讨论】:

    标签: wpf data-binding observablecollection


    【解决方案1】:

    如果您不想丢失任何通知,临时存储可能会起作用,以下可能会起作用,但未经测试:

    public class PausibleObservableCollection<T> : ObservableCollection<T>
    {
        private readonly Queue<NotifyCollectionChangedEventArgs> _notificationQueue
            = new Queue<NotifyCollectionChangedEventArgs>();
    
        private bool _isBindingPaused = false;
        public bool IsBindingPaused
        {
            get { return _isBindingPaused; }
            set
            {
                _isBindingPaused = value;
                if (value == false)
                {
                    while (_notificationQueue.Count > 0)
                    {
                        OnCollectionChanged(_notificationQueue.Dequeue());
                    }
                }
            }
        }
    
        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            if (!IsBindingPaused)
                base.OnCollectionChanged(e);
            else
                _notificationQueue.Enqueue(e);
        }
    }
    

    这应该将集合暂停时发生的所有更改推送到队列中,然后在集合设置为恢复时清空。

    【讨论】:

    • 看起来是一种有前途且清晰的方法。我会试一试,让你知道它是如何工作的......
    • 按照建议工作得很好,我更喜欢这种方法而不是 thedugas 的方法,因为我的 DataGrid 中将有几千个项目。简单而有效。
    【解决方案2】:

    配合@H.B 的回答(我在他/她发布时正在测试) - 您可以将NotifyCollectionChangedAction.Reset Change Action 作为事件参数传递给 CollectionChanged 事件。请注意,这在大型集合上效率不高。

    public class PausibleObservableCollection<T> : ObservableCollection<T>
    {
        private bool _isPaused = false;
        public bool IsPaused 
        { 
          get { return _isPaused; } 
          set 
          { 
              _isPaused = value;
              if (!value)
              { this.OnCollectionChanged(new System.Collections.Specialized.NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction.Reset)); }
    
          } 
        }
    
        protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (!IsPaused)
            { base.OnCollectionChanged(e); }
        }
    }
    

    【讨论】:

    • 我试过了,按预期工作。但是,我的 DataGrid 中将有几千个项目。正如我所读到的,NotifyCollectionChangedAction.Reset 基本上告诉 Grid 绑定所有项目 - 所以你关于性能的提示是至关重要的。但很高兴知道,有这样一个选项。
    猜你喜欢
    • 1970-01-01
    • 2017-02-08
    • 2011-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-31
    • 2013-01-02
    相关资源
    最近更新 更多