WPF MVVM绑定嵌套属性

本文关键字:属性 嵌套 绑定 MVVM WPF | 更新日期: 2023-09-27 18:02:38

我正在创建一个应用程序,用户可以在其中编辑子节点的主数据,我试图通过保存他们对子节点所做的更改来为用户创建一个无缝的体验。

我有一个模型叫Child。

class Child
{
    [Key]
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string Surname { get; set; }
}

我有一个视图(ChildMasterDataView),显示的FirstName和姓氏的文本框是可编辑的。

<!--First name-->
<Label Content="First name:" />
<TextBox Text="{Binding Path=Child.FirstName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
<!--Surname-->
<Label Content="Surname:" />
<TextBox Text="{Binding Path=Child.Surname, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>

我有一个类来处理INotifyPropertyChanged接口的实现。

public class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChangedEvent(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

我有一个ViewModel,当各自的属性被更改时,它应该保存对Firstname和姓氏所做的更改。问题是Firstname和姓氏是子类的嵌套属性,并且没有触发PropertyChanged事件…

class ChildMasterDataViewModel : ObservableObject
{
    private Database db; // Database context
    public ChildViewModel()
    {
        db = new Database();
        Child = db.Children.ToList().Where(e => e.PlbNr == 1).FirstOrDefault(); // Won't be null because child has been chosen earlier
        PropertyChanged += ChildPropertyChanged;
    }
    private Child child;
    public Child Child
    {
        get { return child; }
        set { child = value; RaisePropertyChangedEvent("Child"); }
    }
    private void ChildPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        db.SaveChanges();
    }
}

我可以通过对ViewModel进行以下更改(以及更改视图绑定)来完成我想要的:

class ChildMasterDataViewModel : ObservableObject
{
    private Database db; // Database context
    private Child child;
    public ChildViewModel()
    {
        db = new Database();
        child = db.Children.ToList().Where(e => e.PlbNr == 1).FirstOrDefault(); // Won't be null because child has been chosen earlier
        PropertyChanged += ChildPropertyChanged;
    }
    public string FirstName
    {
        get { return child.FirstName; }
        set { child.FirstName= value; RaisePropertyChangedEvent("FirstName"); }
    }
    public string Surname
    {
        get { return child.Surname; }
        set { child.Surname= value; RaisePropertyChangedEvent("Surname"); }
    }
    private void ChildPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        db.SaveChanges();
    }
}

这不可能是对的,一定有更好的方法吗?

我已经尝试在子类中实现ObservableObject,然后在ViewModel中将子类的PropertyChanged事件订阅到ViewModel的ChildPropertyChanged方法。

WPF MVVM绑定嵌套属性

就我个人而言,我认为没有理由不将一个简单的INotifyPropertyChanged实现放入您的Child模型中-毕竟它具有不断变化的属性。现在您可以直接绑定到它们。

出于同样的原因,为什么保存状态是ViewModel的一部分?我会将其移到模型或单独的持久性管理器中。虚拟机应该对独立于模型的视图的各个方面进行建模。

当依赖属性开始使用绑定时,它尝试将绑定实例转换为INotifyPropertyChanged,然后使用"weak event"订阅事件。依赖性属性不知道内部属性等等,它只是尝试转换为INotifyPropertyChanged并订阅事件。接下来,当事件发生时,依赖属性,使用反射,将获得新的值(这是改进它的方法,你可以编写自己的依赖属性,它将使用表达式,从属性中获取值)