ObservableCollection PropertyChangedイベント
-
05-07-2019 - |
質問
OKですので、 ObservableCollection
をサブクラス化して、プロパティを追加します。残念ながら、 PropertyChanged
イベントは保護されています。基本的に、MVVM WPFアプリのリストにバインドできる SelectedItem
を持つようにサブクラス化します。
クラスのスケルトンは次のとおりです。
public class SelectableList<T> : ObservableCollection<T>
{
public T SelectedItem {get;set;}
}
しかし、次のことはできません:
SelectableList<int> intList = new SelectableList<int>();
intList.PropertyChanged += new PropertyChangedEventHandler(intList_Changed);
アクセス制限のため。これにより、より深い質問をすることになります。 UIが PropertyChanged
イベント(Countプロパティなど)の通知を受け取ることができ、コードビハインドでそれを実行できないのはなぜですか?
頭が回っています。誰かに教えてくれませんか?
解決
SelectableList<int> intList = new SelectableList<int>();
((INotifyPropertyChanged)intList).PropertyChanged +=
new PropertyChangedEventHandler(intList_Changed);
ObservableCollection 明示的にINotifyPropertyChangedを実装 、つまり、インターフェイスのメソッド、プロパティ、イベントにアクセスする前に、インスタンスをインターフェイスにキャストする必要があります。なぜこれが行われるのか、私にはわかりません。 バインディングマークアップ拡張 nは&quotしません;知る&quot; ObservableCollectionsまたはその他のタイプ。型をチェックして、特定のインターフェイス/ベースクラス(INPC、INCC、DependencyObjectなど)を実装または拡張しているかどうかを確認するため、インターフェイスが明示的に実装されているかどうかは気にしません。
他のヒント
ObservableCollection(int .NET 3.5)は、興味深い方法。
protected event PropertyChangedEventHandler PropertyChanged;
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged;
これは、保護された PropertyChanged イベントが内部実装にのみ使用されることを意味する可能性が高いことを意味します。もう1つの INotifyPropertyChanged.PropertyChanged イベントは、
.NET 4.0の実装では、 INotifyPropertyChanged.PropertyChanged イベントが、バグである可能性のある保護された PropertyChanged イベントで使用される同じプライベートデリゲートにフックするようです。修正。これは。NET 4.0での自動イベント実装の処理方法の違い。
修正: ObservableCollectionによって INotifyPropertyChanged.PropertyChanged イベントが発生することを確認したので、Reflectorを使用してObservableCollection実装を確認した結果に基づいて上記で行った仮定不正確でなければなりません。私の推測では、リフレクターは何か奇妙なバグをしていると思われますが、その証拠はまだありません。
サンプルを機能させるには、Willが回答で示したように、これを機能させるために書く必要があります。
SelectableList<int> intList = new SelectableList<int>();
((INotifyPropertyChanged)intList).PropertyChanged +=
new PropertyChangedEventHandler(intList_Changed);
おもしろい?明示的なインターフェースの使用は、特定のインターフェースに必要なメンバーの避けられない衝突を避けるために主に使用されますが、ある意味でメンバーの存在を隠すために使用できます。
サブクラスで導入する独自のカスタムプロパティのプロパティ変更イベントを発生させたい場合は、ObservableCollectionが実装する保護された OnPropertyChanged メソッドのオーバーライドおよび/または呼び出しを調べます。この手法はよく採用されている標準であり、サブクラスが基になるイベントデリゲートにアクセスせずにイベントを発生させたり、イベントを処理したりできます。一般に、サブクラスがイベントハンドラーを独自のベースクラスイベントにフックする代わりに、この方法を使用することも一般的に推奨されます。その他の例については、WinFormsおよびWPFでさまざまなコントロールのイベントがどのように実装されているかを見てください。
新しいプロパティを追加しようとしました
public class ResultCollection<T> : ObservableCollection<T>
{
Boolean _val;
public Boolean Val
{
get
{
return _val;
}
set
{
_val= value;
OnPropertyChanged(new PropertyChangedEventArgs("Val"));
}
}
}
PropertyChanged が protected として定義されていることに気づきませんでした。最後にValプロパティをViewModelに移動しました。
UIは通知を受け取ることができます。これは、PropertyChangedイベントを保護対象として定義するObservableCollectionの制限 JUST です。
FWIW、ObservableCollectionをそのままにして、VMに別のプロパティを追加する方が良いと思います。