13

IList のパラメーターを使用して CollectionChanged を呼び出すと、NotSuportedExceptionObservableCollection/ListCollectionView/CollectionViewが発生する理由について調べています。

//Throws an exception
private void collectionChanged_Removed(IList items)
{
    if (CollectionChanged != null)
        CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, items));
}

このトピックについて話しているいくつかのWebページを見つけました.UIをReset完全に再描画する機能を使用するか、単に各アイテムを呼び出すCollectionChangedか、より創造的な方法を提案しています: http://geekswithblogs.net/NewThingsILearned/ archive/2008/01/16/listcollectionviewcollectionview-doesnt-support-notifycollectionchanged-with-multiple-items.aspx

なぜ見つけられないのですか?私にとって、なぜこれが当てはまるのか意味がありません。

複数のアイテムをすばやく追加したい場合、 Add メソッドは多くのオーバーヘッドを必要とするため、開発サイクルのある時点で私たち全員が直面するこの不足している機能がいつでも実装される可能性はありますか (.Net 5 、C# 6...)。

編集:

私の特定のケースでは、私は自分のクラスを書きました:

public class ObservableList<T> : IList<T>, IList, IEnumerable<T>,
    INotifyCollectionChanged
{
    public event NotifyCollectionChangedEventHandler CollectionChanged;
    //other stuff...
}

それでも、前述のNotSupportedExceptionをスローします。

4

4 に答える 4

4

VirtualBlackFox の回答に触発されてCollectionView、ILSpy のクラスの内部を調べました。Range 操作がサポートされていない主な理由、 が内部的にCollectionView変更ログを使用して、すべての種類の保留中の変更を集中管理し、メッセージを項目ごとにディスパッチするためであると思われます。

まさにその目的により、CollectionView基になるデータを表す複数の UI コントロールで同時に使用される数千のレコードを格納できます。そのため、ビュー情報にアクセスする UI コントロールの整合性を維持するには、レコードの追加または削除をアトミック ベースで行う必要があります。CollectionView のグループ化、並べ替え、およびフィルター処理機能をそれを使用する UI コントロールに渡さずに、一括変更イベントを使用して複数の UI サブスクライバーと増分変更を同期することはできません。

これCollectionViewも派生するSystem.Windows.Threading.Dispatcherため、問題はスレッドで作業項目を管理する方法に関連している可能性があります。ProcessCollectionChanged呼び出しパスには、UI スレッドで個々の変更を具体的に処理する保護されたメソッドが含まれています。そのため、範囲を更新すると、それを使用する UI 要素と対話するために使用するスレッド モデル全体に​​干渉する可能性があります。

CollectionViewパスの消費者をIListtoに入れるのNotifyCollectionChangedEventArgsはばかげていることに完全に同意します。args.NewItems[0]長さ != 1 で内部的にハードコードされているものは特に拒否します。

于 2014-02-07T17:41:52.857 に答える
0

これは主にパフォーマンス上の理由によるものだと思います。もorCollectionViewの -1 値を受け入れないのを見て、私もショックを受けました。したがって、基本的に CollectionView は常にアイテムからインデックスへのマッピングを必要とします。ただし、このマッピングが正確である必要はありません (私の観点からは奇妙です)。NewStartingIndex が正しいインデックスよりも小さいことは許容されます (-1 でない限り)。NewStartingIndexOldStartingIndex

問題の根底にあるのは、Microsoft 内の大部分が、リストがコレクションを実装する唯一の方法だといまだに考えていることにあると思いますが、これはもちろん正しくありません。ここで、作成者はNotifyCollectionChangedEventArgs代替手段 (リンクされたリストやハッシュ コレクションなど) について考えましたが、UI 担当者はそうしませんでした。または、少なくとも、これらのコレクションはめったに表示されないため、これらのコレクションをサポートしたくありませんでした。

于 2014-02-10T17:16:43.747 に答える
0

一時的な解決策は役に立ちません。問題を隠しているだけです。解決策は、オブザーバーにまったく新しいリストを提供するイベントを作成することにあります。そうすれば、Microsoft はオブザーバーの種類ごとに効率的な範囲ハンドラーを実装する必要がなくなります。

于 2014-02-12T15:14:10.853 に答える