问题
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