Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
И непонятно, зачем Вы делаете «collection.ToList()». Вам не нужен список внутри реализации. Зачем лишнюю память занимать?
foreach (var item in items)Чтобы исключить возможный бесконечный цикл ниже:
Напишите, пожалуйста, в комментах реализацию SuspendNotification и ResumeNotification.
P. S. Не могли бы Вы ещё привести конкретные примеры «некоторые контролы WPF не работают с изменениями коллекции не по одному элементу, а по несколько.»? Я с таким не встречался. Чисто для самообразования.
private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
if (sender != this.ItemsInternal && args.Action != NotifyCollectionChangedAction.Reset)
return;
switch (args.Action)
{
case NotifyCollectionChangedAction.Add:
if (args.NewItems.Count != 1)
throw new NotSupportedException(System.Windows.SR.Get("RangeActionsNotSupported"));
this.OnItemAdded(args.NewItems[0], args.NewStartingIndex);
break;
case NotifyCollectionChangedAction.Remove:
if (args.OldItems.Count != 1)
throw new NotSupportedException(System.Windows.SR.Get("RangeActionsNotSupported"));
this.OnItemRemoved(args.OldItems[0], args.OldStartingIndex);
break;
Напишите, пожалуйста, в комментах реализацию SuspendNotification и ResumeNotification.
this.CheckReentrancy();, который все-таки должен быть. Иначе в процессе обработки данных в обработчиках события CollectionChanged, актуальность данных не гарантируется. PropertyChanged
PropertyChanged
OnCollectionChanged
public class ObservableCollectionEx<T> : ObservableCollection<T>
{
private int m_RefreshDeferred;
private bool m_Modified;
/// <summary>
/// Raises the <see cref="E:CollectionChanged" /> event.
/// </summary>
/// <param name="e">The instance containing the event data.</param>
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (m_RefreshDeferred > 0)
{
m_Modified = true;
return;
}
base.OnCollectionChanged(e);
}
/// <summary>
/// Отложить посылку уведомлений об изменении состава коллекции.
/// </summary>
/// <returns>Дескриптор.</returns>
public DeferRefreshHelper DeferRefresh()
{
return new DeferRefreshHelper(this);
}
/// <summary>
/// Дескриптор отложенных изменений.
/// </summary>
public struct DeferRefreshHelper : IDisposable
{
private ObservableCollectionEx<T> m_Owner;
internal DeferRefreshHelper(ObservableCollectionEx<T> owner)
{
if (null == owner)
throw new ArgumentNullException("owner");
m_Owner = owner;
m_Owner.m_RefreshDeferred++;
}
/// <summary>
/// Уменьшить счетчик отложенной посылки обновлений.
/// </summary>
public void Dispose()
{
if (null == m_Owner)
return;
var temp = m_Owner;
m_Owner = null;
if (0 == --temp.m_RefreshDeferred && temp.m_Modified)
temp.OnCollectionChanged(new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Reset));
}
}
}
Функциональность с Range в ObservableCollection