0

以下のような一括追加をサポートし、WPF UI にバインドするために ObservableCollection を実装しました -

public void  AddRange(IEnumerable<T> list)
        {
            lock (_lock)
            {
                if (list == null)
                {
                    throw new ArgumentNullException("list");
                }

                _suspendCollectionChangeNotification = true;
                var newItems = new List<T>();

                foreach (T item in list)
                {
                    if (!Contains(item))
                    {
                        Add(item);
                        newItems.Add(item);
                    }
                }
                _suspendCollectionChangeNotification = false;

                var arg = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newItems);
                OnCollectionChanged(arg);  //NotifyCollectionChangedAction.Reset works!!!
            }
        }
    }

    public override event NotifyCollectionChangedEventHandler CollectionChanged;

            protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
            {
                NotifyCollectionChanged(e);
            }

            internal void NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
            {
                if (IsCollectionChangeSuspended)
                {
                    return;
                }

                NotifyCollectionChangedEventHandler handler = CollectionChanged;
                if (handler != null)
                {
                    if (Application.Current != null && !Application.Current.Dispatcher.CheckAccess())
                    {
                        Application.Current.Dispatcher.Invoke(DispatcherPriority.DataBind,handler, this, e);
                    }
                    else
                    {
                        handler(this, e);
                    }
                }
            }

    private bool IsCollectionChangeSuspended
    {
        get { return _suspendCollectionChangeNotification; }
    }

このエラーが表示されます - {「コレクションが変更されました。列挙操作が実行されない可能性があります。」}

しかし、NotifyCollectionChangedAction.Addtoを変更してNotifyCollectionChangedAction.Reset変更されたリストを渡さないと、UI に正しくバインドされます。NotifyCollectionChangedAction.Addでも、変化を観察できるようなものを使いたいです。

誰でも私を修正してもらえますか?

4

1 に答える 1

2

内部IList<T>を使用してアイテムを追加する場合Add、メソッドを使用するなどのすべてのイベントを通知しません。

Addメソッドは次のように機能します。

  1. チェック再入可能性
  2. InsertItem
  3. OnPropertyChanged("カウント");
  4. OnPropertyChanged("アイテム[]");
  5. OnCollectionChanged(NotifyCollectionChangedAction.Add、アイテム、インデックス);

したがって、Add メソッドをスキップしてアイテムを基になるコレクションに直接追加すると、これが wok に取得される可能性があります。

例: (未テスト)

public void AddRange(IEnumerable<T> rangeItems)
{
    foreach (var item in rangeItems)
    {
         Items.Add(item);
    }

            base.OnPropertyChanged(new PropertyChangedEventArgs("Count"));
            base.OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
            var arg = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, rangeItems);
            OnCollectionChanged(arg);
}
于 2013-09-25T21:42:41.677 に答える