C# 与MVVM文本框中的自定义对象绑定

C# 与MVVM文本框中的自定义对象绑定,c#,xaml,mvvm,data-binding,C#,Xaml,Mvvm,Data Binding,我已经开始学习一些基本应用程序的MVVM,我刚刚遇到了以下绑定问题 我的视图中有两个文本框,分别是-学生姓名和学生年份。我在viewmodel中实现了一个学生类及其属性。但是,实际的学生类在我的模型层中 <TextBox x:Name="StuName" Text="{Binding Path=MyStudent.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> <TextBox x:Name="

我已经开始学习一些基本应用程序的MVVM,我刚刚遇到了以下绑定问题

我的视图中有两个文本框,分别是-学生姓名和学生年份。我在viewmodel中实现了一个学生类及其属性。但是,实际的学生类在我的模型层中

<TextBox x:Name="StuName" 
Text="{Binding Path=MyStudent.Name, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />   


<TextBox x:Name="StuYear" 
Text="{Binding Path=MyStudent.Year, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
模型(学生班):

我可以看到,在将值从VM绑定到视图时,一切都很好。但是,另一种方式是在这里表现得有点狡猾

当我在文本框中更改名称/年份时,控件必须位于Viewmodel的Set属性上?相反,它直接进入模型的Set属性

例如,当我修改txtbox'StuName'时,将调用Student类的SET方法。但不设置Viewmodel(MyStudent对象)的方法

我不知道为什么会这样。是因为我直接将Student.Name绑定到文本框吗?在Viewmodel类中处理此集合操作的备选方案有哪些

提前谢谢


PS:我已经正确地实现了INotifyPropertyChanged接口,其他绑定(原语数据类型)也可以与其他控件一起正常工作

这是正常行为,因为绑定到MyStudent.Name。 因此,永远不会调用Mystudent setter,因为实例永远不会更改。
之所以调用名称的setter,是因为实际上绑定的目的地就是名称的setter。

这是正常的行为,因为绑定到MyStudent.name。 因此,永远不会调用Mystudent setter,因为实例永远不会更改。
之所以调用名称的setter,是因为实际上绑定的目的地就是名称的setter。

这是正常的行为,因为绑定到MyStudent.name。 因此,永远不会调用Mystudent setter,因为实例永远不会更改。
之所以调用名称的setter,是因为实际上绑定的目的地就是名称的setter。

这是正常的行为,因为绑定到MyStudent.name。 因此,永远不会调用Mystudent setter,因为实例永远不会更改。
之所以调用名称的setter,是因为实际上绑定的目的地就在这里。

正如Philip Stuyck在中正确指出的那样,ViewModel只为
学生
实例提供了一个setter,它永远不会更改。因此,永远不会调用ViewModel上的setter。绑定将转到该实例的name属性

另一种方法是在ViewModel中显式包装name属性。这允许在模型和视图模型之间更清晰地分离关注点。也就是说,现在您的模型实现了IMO属于ViewModel的
INotifyPropertyChanged
,因为通常它只用于触发视图更新。您的ViewModel如下所示:

class StudentViewModel
{
    private Student _myStudent = new Student();

    public string Name
    {
        get { return _myStudent.Name ; }
        set
        {
            if (value != _myStudent.Name )
            {
                _myStudent.Name = value;
                OnPropertyChanged("Name");                       
            }
        }
    }
}

另一方面,您的模型变得更简单,因为它不再需要实现
INotifyPropertyChanged

正如Philip Stuyck在中正确指出的那样,ViewModel只有一个用于
Student
实例的setter,它永远不会改变。因此,永远不会调用ViewModel上的setter。绑定将转到该实例的name属性

另一种方法是在ViewModel中显式包装name属性。这允许在模型和视图模型之间更清晰地分离关注点。也就是说,现在您的模型实现了IMO属于ViewModel的
INotifyPropertyChanged
,因为通常它只用于触发视图更新。您的ViewModel如下所示:

class StudentViewModel
{
    private Student _myStudent = new Student();

    public string Name
    {
        get { return _myStudent.Name ; }
        set
        {
            if (value != _myStudent.Name )
            {
                _myStudent.Name = value;
                OnPropertyChanged("Name");                       
            }
        }
    }
}

另一方面,您的模型变得更简单,因为它不再需要实现
INotifyPropertyChanged

正如Philip Stuyck在中正确指出的那样,ViewModel只有一个用于
Student
实例的setter,它永远不会改变。因此,永远不会调用ViewModel上的setter。绑定将转到该实例的name属性

另一种方法是在ViewModel中显式包装name属性。这允许在模型和视图模型之间更清晰地分离关注点。也就是说,现在您的模型实现了IMO属于ViewModel的
INotifyPropertyChanged
,因为通常它只用于触发视图更新。您的ViewModel如下所示:

class StudentViewModel
{
    private Student _myStudent = new Student();

    public string Name
    {
        get { return _myStudent.Name ; }
        set
        {
            if (value != _myStudent.Name )
            {
                _myStudent.Name = value;
                OnPropertyChanged("Name");                       
            }
        }
    }
}

另一方面,您的模型变得更简单,因为它不再需要实现
INotifyPropertyChanged

正如Philip Stuyck在中正确指出的那样,ViewModel只有一个用于
Student
实例的setter,它永远不会改变。因此,永远不会调用ViewModel上的setter。绑定将转到该实例的name属性

另一种方法是在ViewModel中显式包装name属性。这允许在模型和视图模型之间更清晰地分离关注点。也就是说,现在您的模型实现了IMO属于ViewModel的
INotifyPropertyChanged
,因为通常它只用于触发视图更新。您的ViewModel如下所示:

class StudentViewModel
{
    private Student _myStudent = new Student();

    public string Name
    {
        get { return _myStudent.Name ; }
        set
        {
            if (value != _myStudent.Name )
            {
                _myStudent.Name = value;
                OnPropertyChanged("Name");                       
            }
        }
    }
}
另一方面,您的模型变得更简单,因为它不再需要实现
INotifyPropertyChanged

感谢您的回复:)+1建议替代解决方案感谢您的回复:)+1建议替代解决方案感谢您的回复:)+1建议替代解决方案感谢您的回复:)+1建议替代解决方案