0

私は WPF と MVVM にまったく慣れていないので、これは非常に明白で些細なことかもしれません。

とにかく、私はこれらのプロパティを持つビューモデルを持っています:

class ViewModel : INotifyPropertyChanged {
    ICollectionView Items; // a list of Items object, wraps _items field, each Item has a Date property
    string Filter; // a filter key, wraps _filter field and calls ApplyFilter() as it is changed
    void ApplyFilter(); // based on the filter key, _items.Filter gets set to some predicate
}

プロパティは、設定時に PropertyChanged イベントを発生させ、すべての一般的な MVVM のものを発生させます。ビューには、Items プロパティにバインドする単純な ItemsControl と、各項目を表示するための派手なデータ テンプレートがあります。

日ごとにグループ化されたアイテムを表示するように要求されているため、各日の日付ヘッダーと、Date プロパティがヘッダーの日付に対応するアイテムのリストが表示されます。

これは厳密には表示の問題であるため、ビュー モデルはそのままにしておくことにしましたが、コンバーターを使用して ICollectionView アイテムをディクショナリに変換します。キーは日付であり、コレクションはその日付のアイテムのサブセットです。

ItemsControl には、日付ヘッダー (ディクショナリ キー) を表示する TextBlock を含む StackPanel と、基本的にアイテム (ディクショナリ値) をリストした古いもののコピーである別の ItemsControl があります。

ビューはうまくレンダリングされますが、フィルターは機能しなくなります。コントロールが項目にバインドされ、ICollectionView が INotifyCollectionChanged を実装しているため、項目リストを変更するときにフィルターが機能し、コンバーターが再実行されてディクショナリが再構築されることを期待していました。そうではありません。フィルターを変更すると ApplyFilter() が呼び出され、_items.Filter が必要な述語に設定されますが、ビューは変更されません。また、ApplyFilter から項目の PropertyChanged を呼び出してみましたが、どちらも機能しません。

明らかに、これがどのように機能するかという私の不自然なシナリオは間違っています。正直に言うと、日付とアイテムのリストをプロパティとして保持する新しいオブジェクトを作成し、VM でそれらのリストを使用することを除けば、アイデアがありません。しかし、私が言ったように、これは厳密にはビューの問題であるため、モデルはアイテムのリストを提供するだけでよく、それらをレンダリングする方法を決定するのはビューの責任です。

どんな助けでも大歓迎です、そして前もって感謝します。

編集: _filter.Filter を変更している場合、実際には変更されていないため、Items の PropertyChanged イベントは実際には発生しないと考えています (内部は変更されていますが、Items 自体は同じままです)。 ICollectionView)。したがって、コンバーターが再びトリガーされることはありません。

この場合、どうすればコンバーターをトリガーできますか? ApplyFilter() を実行した後にアイテムの PropertyChanged を上げても何もしませんでした。

4

1 に答える 1

1

おそらく、単純な ItemsControl+converter の代わりに ListView を使用する方がよい考えでしょうか? ListView には多くの優れた機能があります。仮想化、グループ化など。ICollectionView グループ化プロパティを変更し、テンプレート (GroupStyle) を適用するだけです。

あなたの問題に関しては、あなたの現在の行動は私には理にかなっています。コンバーターを再実行する場合は、新しいメソッド RefreshBinding() を作成して、次のようにする必要があります。

var referenceCopy = Items;
Items = null;//make sure INotifyPropertyCHanged is fired.
Items = referenceCopy; //converter should be called again. 

コンバーターの再実行が必要になった後に呼び出します。しかし、正直に言うと、ICollectionView+Grouping プロパティと ListView を使用するだけです。または、ListView 機能を自分で実装することもできます。コンバーターを使用することは、良い解決策ではないようです。

于 2012-08-24T10:30:10.180 に答える