简体   繁体   English

MVVM中子属性的PropertyChanged

[英]PropertyChanged for child properties in MVVM

I'm struggling a little with the structure of my project still, and ran into an issue which im worried demonstrates that i'm still missing a good understanding of the right way to do things. 我仍在为项目的结构做些挣扎,遇到一个问题,我担心这表明我仍然对正确的做事方式缺乏很好的理解。

What i have currently is: 我目前所拥有的是:

The program displays information for shipping, this is based on an overall project which contains proformas which contains shipments which contains containers (this is simplified for this example) 该程序将显示要运输的信息,这是基于一个包含项目表的整体项目,该项目表包含了包含容器的货运(此示例对此进行了简化)

So in order to keep track of the currently selected objects (Project, proforma etc.) i have a class called ProjectTree which looks similar to this: 因此,为了跟踪当前选择的对象(Project,Proforma等),我有一个名为ProjectTree的类,其外观类似于此:

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

again this is simplified, now since Project itself contains the list of Proformas, i have a function on Project called LoadProformas() which creates a new thread and loads that projects proformas into an ObservableCollection within project itself (the loading is done by a set of IManagers that handle all the data loading, saving etc. ) 再次简化一下,因为Project本身包含Proformas列表,所以我在Project上有一个名为LoadProformas()的函数,该函数创建一个新线程,并将该ObservableCollection投影到项目自身内的ObservableCollection中(加载由一组处理所有数据加载,保存等的IManagers

Now the issue i'm faced with is that say my viewmodel ProformaListViewModel has access to ProjectTree so it can call the LoadProformas() on the Project, i run into the issue of databinding the _ProjectTree.SelectedProject.ProformaList as i wont know when the data has actually been loaded since (afaik) NotifyOfPropertyChange wont flow through into the viewmodel in this scenario. 现在我面临的问题是,我的视图模型ProformaListViewModel可以访问ProjectTree因此它可以在Project上调用LoadProformas() ,我遇到了对_ProjectTree.SelectedProject.ProformaList进行数据绑定的问题,因为我不知道何时获取数据由于(afaik) NotifyOfPropertyChange在这种情况下不会流入视图模型中,因此已被实际加载。 Now i could always use the EventAggregator and fire an event when the data is loaded (and this is what I've done in the past) however whenever i look at this it seem a bit... haphazard, to be firing unbound events from an child object to the parent. 现在,我总是可以使用EventAggregator并在加载数据时触发一个事件(这是我过去所做的事情),但是每当我看到此内容时,似乎有点...偶然地从中触发未绑定的事件父对象的子对象。

Have i missed something critical in my understanding here? 我错过了一些对我的理解很重要的事情吗? Or would using the event be a reasonable way to accomplish what i need? 还是使用该事件是完成我需要的合理方式?

EDIT: 编辑:

Just to clear this up, the reason im trying to do this is because each project has a list of proformas and each proforma a list of shipments etc. Originally the managers handled the lists of objects as well as loading and saving, but i found that having them totally uncoupled what causing issue when trying to do work with a project based on its shipments (for example) 只是为了澄清这一点,我试图这样做的原因是因为每个项目都有一个形式清单,每个形式都有装运清单等。最初,管理人员处理对象清单以及装载和保存,但是我发现让他们完全脱离耦合,试图根据项目的出货量来处理项目时(例如)

In my opinion, you shouldn't be using any Selected... properties in your data type/model classes... those properties belong in your view model classes. 我认为,您不应该在数据类型/模型类中使用任何Selected...属性...这些属性属于您的视图模型类。 Furthermore, unless you actually use an object in your work that is called a ProjectTree , I wouldn't name your object that... just stick to real world names. 此外,除非您在工作中实际使用了一个名为ProjectTree的对象,否则我不会将您的对象命名为...只是坚持现实世界的名称。

Also, I'd advise against putting functionality in your data type classes... in my opinion (for the most part) they should just be containers for data. 另外,我建议不要将功能放在您的数据类型类中……在我看来(在大多数情况下)它们应该只是数据的容器。 I would structure the view model like this (I'm ignoring the INotifyPropertyChanged interface in this example, but you'll need to correctly implement it): 我将这样构造视图模型(在此示例中,我忽略了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() {}             
}

Next, you mentioned that you're using the EventAggregator instead of the INotifyPropertyChanged interface... it seems to me that you are making your life more difficult than it needs to be as the INotifyPropertyChanged interface can be used for this just fine. 接下来,您提到您使用的是EventAggregator而不是INotifyPropertyChanged接口...在我看来,这使您的生活变得更加艰难,因为INotifyPropertyChanged接口可以正常使用。 Implement it in both your data type classes and your view model classes and then it will work for every property. 在您的数据类型类视图模型类中都实现它,然后它将对每个属性都适用。 Remember, you can add a PropertyChanged handler in your view model(s) too. 请记住,您也可以在视图模型中添加PropertyChanged处理程序。

did you try to call manually to 您是否尝试手动拨打

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

after loading the projects proformas ? 加载项目形式后?

Each of your viewModel classes (your Project, Proforma, and shipment classes may in this case be acting as both the model and viewModel) need to implement the INotifyPropertyChanged interface. 您的每个viewModel类(在这种情况下,您的Project,Proforma和shipping类都可能同时充当模型和viewModel)都需要实现INotifyPropertyChanged接口。 Then your view should databind directly to the property SelectedProject.ProformaList . 然后,您的视图应直接数据绑定到属性SelectedProject.ProformaList Since the list is an ObservableCollection already, your view will be notified when items are added or removed. 由于列表已经是ObservableCollection ,因此在添加或删除项目时将通知您的视图。 You then just need to ensure that the PropertyChanged notification is raised when the ProformaList property itself is changed. 然后,您只需要确保在更改ProformaList属性本身时引发PropertyChanged通知。

Since every property that is bound in the View should Notify of Property Changes, each level of your data 'tree' (Project, Proforma, Shipment) can be changed independently and still update the view. 由于视图中绑定的每个属性都应通知属性更改,因此数据“树”的每个级别(项目,形式,运输)都可以独立更改,并且仍会更新视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM