【问题标题】:WPF MVVM design ViewModelWPF MVVM 设计 ViewModel
【发布时间】:2013-01-02 02:03:34
【问题描述】:

我有以下型号:

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

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

我有两个视图:

  • 一个用于显示所有姓氏和城市名称的人 一个 DataGrid(AllPersonsViewModel)
  • 用于添加新人员 (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;}
    }
}

然后我添加了用于添加新人员的属性。在视图中,我需要一个用于 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.Name”而不是额外的属性 CityName。网格也是只读的。

【问题讨论】:

  • 还有什么问题?
  • 最后一段:“这是正确的方法吗?这对我来说似乎有点多余。在 AllPersonsView 的网格中,我还可以直接绑定到“SelectedCity.Name”而不是额外的属性 CityName 。”
  • 是的,我可以阅读。我的意思是你的问题很模糊......这里有错误或正确的方法吗?如果它有效,它可能是正确的,如果不是,那么它可能是错误的。我不认为 Cities 应该是 Person 的属性。

标签: c# .net wpf mvvm viewmodel


【解决方案1】:

你有多个问题;

1 - 您无需在 AllPersonViewModel 中声明可观察的视图模型集合。只需声明 Person 的 ObservableCollection。

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

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

【讨论】:

  • 感谢您的回答。对于 3,我必须将 INotifyPropertyChanged 添加到我的 Person 模型中,对吗?
  • @LuckyStrike 是的;如果你没有绑定 ObservableCollections,你需要实现 INotifyPropertyChanged。
【解决方案2】:

您的问题真的归结为“可以将我的模型直接暴露在视图中吗?”一些纯粹主义者会说不,而另一些人会说拥有一个包装模型而不添加任何新功能的视图模型是多余的。

在我看来,这取决于手头的任务,但是当您需要添加不属于模型的其他状态时,“跳过”视图模型可能会回来并咬住您。如果对使用视图模型有疑问,但例如在列表中公开简单模型对象时,您通常不需要视图模型提供的额外层。

在您的情况下,您选择了“纯粹”解决方案,并且由于您的模型对象不支持INotifyPropertyChanged,如果模型属性被多个来源更改,您将无法摆脱视图模型。但是,您可以绑定到SelectedCity.Name,而不是提供CityName 属性。 WPF 支持数据绑定表达式中的属性导航。

如需更深入了解此主题,您可以 google mvvm expose model

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-11
    • 2011-08-02
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多