Pause the Updates to DataGrid of bound ObservableCollection<T>

纵然是瞬间 提交于 2019-12-18 06:48:15

问题


Is there a way to pause the NotifyCollectionChanged event of an ObservableCollection? I thought something like the following:

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

This pauses the notification indeed, but obviously the then left out (but still added) items are within the NotifyCollectionChangedEventArgs and are therefore not passed to the bound DataGrid when I enable the notification again.

Will I have to come up with a custom implementation of a collection in order to control this aspect?


回答1:


If you do not want to loose any notifications a temporary storage might work, the following might work but is untested:

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

This should push every change that happens while the collection is paused into a queue, which then is emptied once the collection is set to resume.




回答2:


To go along with @H.B's answer (I was testing while he/she posted) - you can pass the NotifyCollectionChangedAction.Reset Change Action as an event argument to the CollectionChanged event. Note that this will not be efficient on large collections.

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



回答3:


If you are trying to achieve adding a list of items to the observable collection with only a single notify. You could try implementing an AddRange. I think this may be a good example.



来源:https://stackoverflow.com/questions/5490816/pause-the-updates-to-datagrid-of-bound-observablecollectiont

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!