WPF MVVM设计视图模型

本文关键字:视图 模型 MVVM WPF | 更新日期: 2023-09-27 17:54:04

我有以下模型:

public class Person
{
    public string LastName{get;set;}
    public City City {get;set;}
}
public class City
{
    public string Name {get;set;}
}

我有两个视图:

  • 一个用于显示所有具有LastName和城市名称的person一个DataGrid (AllPersonsViewModel)
  • 一个用于添加新的Person (PersonViewModel)
我AllPersonsViewModel

:

public class AllPersonViewModel : ViewModel
{
    public ObservableCollection<PersonViewModel> PersonViewModels {get;set;}
}

我从以下PersonViewModel开始:

public class PersonViewModel : ViewModel
{
    private Person _person;
    public string Name
    {
        get { return _person.Name;}
        set { _person.Name = value; RaisePropertyChange("Name");}
    }
    public string CityName
    {
        get { return _person.City.Name;}
    }
}

然后我添加了用于添加新Person的属性。在视图中,我需要一个用于PersonName的文本框和一个用于选择城市的组合框:

public class PersonViewModel : ViewModel
{
    private Person _person;
    public string Name
    {
        get { return _person.Name;}
        set { _person.Name = value; RaisePropertyChange("Name");}
    }
    public string CityName
    {
        get { return _person.City.Name;}        
    }
    public City SelectedCity 
    { 
        get { return _person.City;}
        set { _person.City = value; RaisePropertyChange("SelectedCity");}
    }
    public ObservableCollection<City> Cities {get;set;} 
}

这是正确的方法吗?我觉得这有点多余。在AllPersonsView的网格中,我还可以直接绑定到"SelectedCity"。而不是额外的属性CityName。这个网格也是只读的

WPF MVVM设计视图模型

你有很多问题;

1 -你不需要在AllPersonViewModel中声明一个视图模型的可观察集合。只需声明Person的ObservableCollection

2 -不添加CityName属性;如你所说,不需要。

3-不添加Name属性。将文本框绑定到Person的Name属性

你的问题真的归结为"它是OK的暴露我的模型直接向视图?"一些纯粹主义者会说不,而另一些人会说,用一个视图模型来包装模型而不添加任何新功能是多余的。

在我看来,这取决于手头的任务,但是当你需要添加不属于模型的额外状态时,"跳过"视图模型可能会回来咬你。如果不确定使用视图模型,但是当在列表中显示简单的模型对象时,通常不需要视图模型提供的额外层。

在你的情况下,你选择了"纯粹"的解决方案,因为你的模型对象不支持INotifyPropertyChanged,你不能摆脱视图模型,如果一个模型属性被多个源改变。但是,您可以绑定到SelectedCity.Name,而不是提供CityName属性。WPF支持数据绑定表达式中的属性导航。

关于这个主题的更多信息,你可以谷歌mvvm expose model