Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF MVVM绑定嵌套属性_C#_Wpf_Mvvm_Binding - Fatal编程技术网

C# WPF MVVM绑定嵌套属性

C# WPF MVVM绑定嵌套属性,c#,wpf,mvvm,binding,C#,Wpf,Mvvm,Binding,我正在创建一个应用程序,用户可以在其中编辑孩子的主数据,我正在尝试通过保存他们对孩子所做的更改来为用户创建无缝体验 我有一个叫Child的模型 class Child { [Key] public int ID { get; set; } public string FirstName { get; set; } public string Surname { get; set; } } 我有一个视图(ChildMasterDataView),它在可编辑的文本框

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

我有一个叫Child的模型

class Child
{
    [Key]
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string Surname { get; set; }
}
我有一个视图(ChildMasterDataView),它在可编辑的文本框中显示名字和姓氏

<!--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}"/>
我有一个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进行以下更改(以及ofc更改视图绑定)来实现我想要的功能:

这不可能是对的,一定有更好的办法


我尝试在子类中实现ObserveObject,然后在ViewModel中将子类的PropertyChanged事件订阅到ViewModel的ChildPropertyChanged方法。这不起作用。

就我个人而言,我认为没有理由不将一个简单的
INotifyPropertyChanged
实现放到您的子模型中——毕竟它的属性正在更改。现在您可以直接绑定到它们


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

当依赖项属性开始使用绑定时,它会尝试将绑定实例转换为INotifyPropertyChanged,然后使用“弱事件”订阅事件。所以dependecy属性对内部属性等一无所知,它只是尝试转换为INotifyPropertyChanged和suscribe to event。接下来,当事件发生时,使用反射的dependency peroperty将获得新的值(这是一种改进方法,您可以编写自己的dependency属性,它将是use Expression,用于从属性获取值)

您只需要三种方法即可。1) 包裹模型-你已经做到了,我想InotifyPropertyChanged会更容易。2) 将INotifyPropertyChanged直接添加到模型中。3) 您将创建一个Statalone类,该类实现INotifypropertyChanged或派生自ObservableObject。这个类必须将您的模型作为输入进行处理,并自行处理,以初始化您将绑定的属性。您还需要进行回转换。如果您绑定到它,它可能应该实现INotifyPropertyChanged。还有IDataErrorInfo。你能告诉我你是如何与他们结合的吗?因为我试过了,但没能成功。如何通过我的模型保存数据?没有特殊的绑定,您的XAML非常好。您只需要在子类上实现INotifyPropertyChanged。不过,请注意,您当前的每一次击键都会触发数据库更新…我已经在模型中再次实现了INotifyPropertyChanged接口,但这次我也使用了DataTemplate,并且使用DataTemplate它可以工作。如果没有DataTemplate,它将无法工作。不过我有一个新问题,我的组合框中有不同的ItemSource,它们不再工作了,因为我认为它们被ContentControl&DataTemplate覆盖或取消。
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();
    }
}
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();
    }
}