简体   繁体   English

父属性更改时嵌套属性的 WPF 绑定更新通知

[英]WPF binding update notification for nested property when parent property changes

I have a ViewModel with a complex property type and want to bind my view to a nested property of this object.我有一个具有复杂属性类型的 ViewModel,并希望将我的视图绑定到此对象的嵌套属性。

My ViewModel is implementing INotifyPropertyChanged (or do be extact BaseViewModel is implementing it).我的 ViewModel 正在实现INotifyPropertyChanged (或者确实BaseViewModel正在实现它)。 The class of the parent property is not implementing INotifyPropertyChanged .父属性的类没有实现INotifyPropertyChanged

The class Car is not implementing INotifyPropertyChanged .类 Car 没有实现INotifyPropertyChanged But I'm not changing the property Manufacturer , I change the MyCarProperty property, and so I expect that the OnNotifyPropertyChanged event will trigger the value update?但是我没有更改属性Manufacturer ,而是更改了MyCarProperty属性,所以我希望OnNotifyPropertyChanged事件会触发值更新?

When I'm updating the value of the parent property, the nested property is not updating.当我更新父属性的值时,嵌套属性没有更新。 Can you tell me how can I implement this functionality?你能告诉我如何实现这个功能吗?

ViewModel视图模型

public class ViewModel : BaseViewModel
{
    private Car _myCarProperty;

    public Car MyCarProperty
    {
        get { return _myCarProperty; }
        set
        {
            if (value == _myCarProperty) return;

            _myCarProperty = value;
            OnPropertyChanged();
        }
    }
}

Binding in the View在视图中绑定

<TextBlock Text="{Binding Path=MyCarProperty.Manufacturer}" />

When I change the value of MyCarProperty the View does not update.当我更改MyCarProperty的值时,视图不会更新。

Thanks for any help!谢谢你的帮助!

Edit: OnPropertyChanged() implementation编辑: 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

"The class Car is not implementing INotifyPropertyChanged. But I'm not changing the property Manufacturer, I change the MyCarProperty property, and so I expect that the OnNotifyPropertyChanged event will trigger the value update?" “类 Car 没有实现 INotifyPropertyChanged。但我没有更改属性制造商,我更改了 MyCarProperty 属性,所以我希望 OnNotifyPropertyChanged 事件会触发值更新?”

Nope, it won't trigger the value update a level down.不,它不会触发值更新一个级别。 Bindings don't listen to property changes for an entire path, they listen only to the object that they're bound to.绑定不侦听整个路径的属性更改,它们只侦听绑定到的对象。

I see a couple options off the top of my head (in order of my preference when I run into this):我在脑海中看到了几个选项(按照我遇到这个的偏好顺序):

  1. Bind to the car, not the sub property, and create a data template that displays what you want out of it.绑定到汽车,而不是子属性,并创建一个数据模板来显示您想要的内容。
  2. Manually kick the binding by calling UpdateTarget on it's BindingExpression when you need to.在需要时通过在其BindingExpression上调用 UpdateTarget 来手动启动绑定。

I know it looks like there's a lot more to learn on the data template route, but I promise you that data templates will prove vastly more powerful, scalable, maintainable, and useful than manually kicking bindings as you work more in WPF.我知道它看起来像有很多东西要学数据模板路线上,但我向你保证数据的模板将更加强大,可扩展性,可维护性和有用的证明比手动踢绑定,你在WPF更多的工作。 (Also, once you understand them, I think they're actually less work than manually kicking bindings). (另外,一旦你理解了它们,我认为它们实际上比手动踢绑定更少的工作)。

Good luck!祝你好运!

The accepted answer explains how to handle the case where a sub-property on a Binding Source is changed and you wish to update the view - which is not what the question is asking.接受的答案解释了如何处理绑定源上的子属性发生更改并且您希望更新视图的情况 - 这不是问题所要问的。 WPF will in fact respond to changes from many levels down, so long as you are notifying changes for any properties being changed within the specified path. WPF 实际上会响应从多个级别向下的更改,只要您通知指定路径内更改的任何属性的更改。

As for this:至于这个:

"The class Car is not implementing INotifyPropertyChanged. But I'm not changing the property Manufacturer , I change the MyCarProperty property, and so I expect that the OnNotifyPropertyChanged event will trigger the value update?" “类 Car 没有实现 INotifyPropertyChanged。但我没有更改属性 Manufacturer ,我更改了 MyCarProperty 属性,所以我希望 OnNotifyPropertyChanged 事件会触发值更新?”

WPF handles this already. WPF 已经处理了这个问题。

In your example, ViewModel is the Binding Source.在您的示例中, ViewModel是绑定源。 When you set MyCarProperty (firing the NotifyPropertyChanged event), WPF will re-evaluate the Binding Target Value using the Binding Path for the new Binding Source object - updating your view with the new Manufacturer .当您设置MyCarProperty (触发NotifyPropertyChanged事件)时,WPF 将使用绑定源对象的绑定路径重新评估绑定目标值 - 使用新的Manufacturer更新您的视图。

I have tested this with a simple WPF app - it also holds true for very deeply nested Paths:我已经用一个简单的 WPF 应用程序对此进行了测试——它也适用于非常深的嵌套路径:

https://pastebin.com/K2Ct4F0F https://pastebin.com/K2Ct4F0F

<!-- 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}" />

I'm not an WPF expert, but I think it's because you've chosen the wrong path.我不是 WPF 专家,但我认为这是因为您选择了错误的路径。

<TextBlock Text="{Binding Path=MyCarProperty, Value=Manufacturer}" />

update:更新:

<TextBlock Text="{Binding Source=MyCarProperty, Path=Manufacturer}" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM