複雑なプロパティタイプのViewModelがあり、ビューをこのオブジェクトのネストされたプロパティにバインドしたいと考えています。
私のViewModelはINotifyPropertyChanged
を実装しています(または正確にはBaseViewModel
が実装しています)。親プロパティのクラスはINotifyPropertyChanged
を実装していません。
親プロパティの値を更新しているとき、ネストされたプロパティは更新されません。この機能を実装する方法を教えてください。
ViewModel
public class ViewModel : BaseViewModel
{
private Car _myCarProperty;
public Car MyCarProperty
{
get { return _myCarProperty; }
set
{
if (value == _myCarProperty) return;
_myCarProperty = value;
OnPropertyChanged();
}
}
}
ビューでのバインド
<TextBlock Text="{Binding Path=MyCarProperty.Manufacturer}" />
MyCarProperty
の値を変更しても、ビューが更新されません。
助けてくれてありがとう!
編集:OnPropertyChanged()の実装
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion INotifyPropertyChanged
「クラスCarはINotifyPropertyChangedを実装していません。しかし、プロパティManufacturerを変更していません。MyCarPropertyプロパティを変更しているので、OnNotifyPropertyChangedイベントが値の更新をトリガーすると思いますか?」
いいえ、レベルダウンの値更新はトリガーされません。バインディングは、パス全体のプロパティの変更をリッスンするのではなく、バインドされているオブジェクトのみをリッスンします。
頭のてっぺんからいくつかのオプションが表示されます(これに遭遇したときの好みの順に):
BindingExpression
でUpdateTargetを呼び出して、バインディングを手動でキックします。データテンプレートルートについて学ぶことはまだまだたくさんあるようですが、データテンプレートが大幅により強力でスケーラブルであることを証明することをお約束します。 WPFでより多くの作業を行うため、手動でバインディングをキックするよりも保守が容易で便利です。 (また、それらを理解すると、手動でバインディングをキックするよりも実際には少ない作業だと思います)。
幸運を!
受け入れられた回答は、バインディングソースのサブプロパティが変更され、ビューを更新したい場合の処理方法を説明しています-これは質問が求めているものではありません。実際、WPFは、指定されたパス内で変更されたプロパティの変更を通知している限り、多くのレベルからの変更に応答します。
これに関して:
「クラスCarはINotifyPropertyChangedを実装していません。しかし、私はプロパティManufacturerを変更していません。MyCarPropertyプロパティを変更しているので、OnNotifyPropertyChangedイベントが値の更新をトリガーすることを期待しています。 ?」
WPFはこれをすでに処理しています。
あなたの例では、ViewModel
がバインディングソースです。 MyCarProperty
を設定すると(NotifyPropertyChanged
イベントを発生させる)、WPFはnewバインディングのバインディングパスを使用してバインディングターゲット値を再評価しますソースオブジェクト-新しいManufacturer
でビューを更新します。
単純なWPFアプリでこれをテストしました。これは、非常に深くネストされたパスにも当てはまります。
<!-- When MyViewModel notifies that "MyCarProperty" has changed, -->
<!-- this binding updates the view by traversing the given Path -->
<TextBlock Text="{Binding Path=MyCarProperty.Model.SuperNested[any][thing][you][want][to][try][and][access].Name}" />
私はWPFの専門家ではありませんが、間違ったパスを選択したためだと思います。
<TextBlock Text="{Binding Path=MyCarProperty, Value=Manufacturer}" />
更新:
<TextBlock Text="{Binding Source=MyCarProperty, Path=Manufacturer}" />