PropertyMhanged用于MVVM中的子属性

时间:2013-11-26 12:55:42

标签: c# wpf mvvm

我对项目的结构仍然有点挣扎,并遇到一个问题,我担心这表明我仍然缺乏对正确做事方式的理解。

目前我所拥有的是:

程序显示运输信息,这是基于一个整体项目,其中包含包含包含容器的货件的形式表(本例中简化了这一点)

因此,为了跟踪当前选择的对象(项目,形式等),我有一个名为ProjectTree的类,它看起来与此类似:

Public class ProjectTree
{
  Public Project SelectedProject { get; set; }
  Public Proforma SelectedProforma { get; set; }
  public Shipment SelectedShipment { get; set; }
}

这又简化了,现在因为Project本身包含了P​​roformas列表,我在Project上有一个名为LoadProformas()的函数,它创建了一个新的线程并加载了将形式项目投影到项目本身的ObservableCollection中(加载由一组IManagers完成,处理所有数据加载,保存等。)

现在我面临的问题是,我的viewmodel ProformaListViewModel 可以访问ProjectTree,因此它可以调用项目上的LoadProformas(),我遇到了数据绑定_ProjectTree.SelectedProject.ProformaList的问题,因为我不知道数据何时实际加载,因为(afaik)NotifyOfPropertyChange不会流入此场景中的视图模型。现在我总是可以使用EventAggregator并在加载数据时触发一个事件(这是我过去所做的事情)然而每当我看到它时,似乎有点......随意,从而触发未绑定事件父对象的子对象。

我是否错过了我理解中的重要内容?或者使用这个事件是一种合理的方式来完成我需要的东西?

编辑:

为了清楚这一点,我试图这样做的原因是因为每个项目都有一份形式列表和每个形式列表的货物等。最初管理者处理了对象列表以及加载和保存,但是我发现让他们完全解耦在尝试根据货物运行项目时导致问题的原因(例如)

3 个答案:

答案 0 :(得分:3)

在我看来,您不应该在数据类型/模型类中使用任何Selected...属性......这些属性属于您的视图模型类。此外,除非你在你的工作中实际使用一个名为ProjectTree的对象,否则我不会将你的对象命名为...只是坚持现实世界的名字。

另外,我建议不要在您的数据类型类中添加功能......在我看来(大多数情况下)它们应该只是数据的容器。我会像这样构造视图模型(我在这个例子中忽略了INotifyPropertyChanged接口,但是你需要正确地实现它):

public class ProjectViewModel : INotifyPropertyChanged
{
    public ObservableCollection<Project> Projects { get; set; }
    public Project SelectedProject { get; set; }
    public ObservableCollection<Proforma> Proformas { get; set; }
    public Proforma SelectedProforma { get; set; }
    public ObservableCollection<Shipment> Shipments { get; set; }
    public Shipment SelectedShipment { get; set; }

    public void LoadProjects() {}
    public void LoadProformas() {}             
    public void LoadShipments() {}             
}

接下来,您提到您正在使用EventAggregator而不是INotifyPropertyChanged界面...在我看来,您的生活比{I}所需要的更难。 {1}}接口可以用于此就好了。在您的视图模型类的数据类型类中实现它,然后它将适用于每个属性。请记住,您也可以在视图模型中添加INotifyPropertyChanged处理程序。

答案 1 :(得分:0)

您是否尝试手动调用

PropertyChanged(this,new PropertyChangedEventArgs(“ProformaList”));

加载项目形式表后?

答案 2 :(得分:0)

您的每个viewModel类(您的Project,Proforma和货运类在这种情况下都可以充当模型和viewModel)需要实现INotifyPropertyChanged接口。然后,您的视图应直接数据绑定到属性SelectedProject.ProformaList。由于列表已经是ObservableCollection,因此在添加或删除项目时会通知您的视图。然后,您需要确保在更改ProformaList属性本身时引发PropertyChanged通知。

由于视图中绑定的每个属性都应通知属性更改,因此数据的每个级别都会生成一个&#39;树。 (Project,Proforma,Shipment)可以单独更改,仍然可以更新视图。