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

时间:2015-02-12 06:16:48

标签: c# xaml mvvm data-binding

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

我的View中有2个文本框 - Student_name和Student_year。我在我的viewmodel中实现了一个带有其属性的Student类。但是,实际的Student类在我的Model层中。

<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");                       
      }
    }
}

模特(学生班):

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

我可以看到将VM中的值绑定到View的一切正常。但是,另一种方式是在这里表现得有点棘手......

当我在文本框中更改名称/年份时,控件必须落在Viewmodel的Set属性上?相反,它直接转到Model的Set属性。

对于Instance,当我修改txtbox'StuName'时,调用Student类的SET方法。但不是Viewmodel的SET方法(MyStudent对象)。

我不确定为什么这样做会这样。是因为我直接将Student.Name限制在文本框中吗?在Viewmodel类中处理此SET操作的替代方法是什么。

提前致谢。

PS:我已经正确实现了INotifyPropertyChanged接口,并且其他绑定(原始数据类型)与其他控件一起工作正常。

2 个答案:

答案 0 :(得分:2)

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

另一种方法是明确地将View属性包装在ViewModel中。这样可以更清晰地分离Model和ViewModel之间的关注点。即现在你的模型实现了IMO属于ViewModel的INotifyPropertyChanged,因为它通常只用于触发View更新。您的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)

这是正常行为,因为您的绑定是MyStudent.Name。 因此,Mystudent setter永远不会被调用,因为实例永远不会改变。 调用名称的setter是因为实际上这是绑定的目的地。