与 MVVM 文本框中的自定义对象绑定
Binding with custom object in MVVM textbox
我已经开始学习 MVVM 的一些基本应用程序,我刚刚遇到以下绑定问题。
我的视图中有 2 个文本框,比如 - Student_name 和 Student_year。我在我的视图模型中实现了一个 Student class 及其属性。但是,实际的 Student class 在我的模型层中。
<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}" />
视图模型:
private Student _myStudent = new Student();
public Student MyStudent
{
get { return _myStudent ; }
set
{
if (value != _myStudent )
{
_myStudent = value;
OnPropertyChanged("MyStudent");
}
}
}
模特(学生Class):
public string Name
{
get { return _name; }
set
{
if (_name!= value)
{
_name= value;
OnPropertyChanged("Name");
}
}
}
我可以看到将值从 VM 绑定到 View 时一切正常。但是,另一种方式在这里表现得有点棘手..
即使我在文本框中更改 Name/Year,控件也必须位于 Viewmodel 的 Set 属性 上?相反,它直接转到模型的集合 属性。
例如,当我修改txtbox 'StuName'时,调用了Student class的SET方法。但不是 Viewmodel(MyStudent object) 的 SET 方法。
我不确定为什么会这样。是因为我直接绑定了Student.Name到文本框吗?在 Viewmodel class..
中处理此 SET 操作的替代方案是什么
提前致谢。
PS:我已经正确实现了 INotifyPropertyChanged 接口,其余的(原始数据类型的)绑定与其他控件一起工作正常。
这是正常行为,因为您的绑定是 MyStudent.Name。
所以 Mystudent setter 永远不会被调用,因为实例永远不会改变。
名称的 setter 之所以被调用,是因为实际上这就是您的绑定所在的位置。
正如 Philip Stuyck 在 中正确指出的那样,ViewModel 只有 Student
实例的 setter,它永远不会改变。所以 ViewModel 上的 setter 永远不会被调用。绑定转到该实例的名称 属性。
另一种方法是将名称 属性 显式包装在您的 ViewModel 中。这允许更清晰地分离模型和视图模型之间的关注点。 IE。现在你的模型实现了 INotifyPropertyChanged
,IMO 属于 ViewModel,因为通常它只用于触发视图更新。您的 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
。
我已经开始学习 MVVM 的一些基本应用程序,我刚刚遇到以下绑定问题。
我的视图中有 2 个文本框,比如 - Student_name 和 Student_year。我在我的视图模型中实现了一个 Student class 及其属性。但是,实际的 Student class 在我的模型层中。
<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}" />
视图模型:
private Student _myStudent = new Student();
public Student MyStudent
{
get { return _myStudent ; }
set
{
if (value != _myStudent )
{
_myStudent = value;
OnPropertyChanged("MyStudent");
}
}
}
模特(学生Class):
public string Name
{
get { return _name; }
set
{
if (_name!= value)
{
_name= value;
OnPropertyChanged("Name");
}
}
}
我可以看到将值从 VM 绑定到 View 时一切正常。但是,另一种方式在这里表现得有点棘手..
即使我在文本框中更改 Name/Year,控件也必须位于 Viewmodel 的 Set 属性 上?相反,它直接转到模型的集合 属性。
例如,当我修改txtbox 'StuName'时,调用了Student class的SET方法。但不是 Viewmodel(MyStudent object) 的 SET 方法。
我不确定为什么会这样。是因为我直接绑定了Student.Name到文本框吗?在 Viewmodel class..
中处理此 SET 操作的替代方案是什么提前致谢。
PS:我已经正确实现了 INotifyPropertyChanged 接口,其余的(原始数据类型的)绑定与其他控件一起工作正常。
这是正常行为,因为您的绑定是 MyStudent.Name。 所以 Mystudent setter 永远不会被调用,因为实例永远不会改变。 名称的 setter 之所以被调用,是因为实际上这就是您的绑定所在的位置。
正如 Philip Stuyck 在 Student
实例的 setter,它永远不会改变。所以 ViewModel 上的 setter 永远不会被调用。绑定转到该实例的名称 属性。
另一种方法是将名称 属性 显式包装在您的 ViewModel 中。这允许更清晰地分离模型和视图模型之间的关注点。 IE。现在你的模型实现了 INotifyPropertyChanged
,IMO 属于 ViewModel,因为通常它只用于触发视图更新。您的 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
。