MVVM模式和依赖子级

时间:2012-04-27 12:37:34

标签: c# wpf

我正在使用MVVM而且(仍然 - 我对它很新)与模式有点挣扎。我有一个名为Mission的对象,它有两个孩子,网络和平台。任务可能具有1到多个平台,并且具有1或2个网络(主要始终存在,并且备选是可选的)。有一个网络和平台的孩子名为NetworkPlatform,其数量将取决于平台和网络的数量 - 如果有5个平台,他们没有定义备用网络,那么将有5个NetworkPlatforms,否则就是10个。所以如果添加平台我需要添加一个或两个网络平台,具体取决于备用网络是否存在。同样,如果他们选择定义以前不存在的备用网络,我需要为每个平台添加一个网络平台。同上删除。

我有一种伞形ViewModel for Mission,可以像这样实例化一些子ViewModel

public MissionFullDataViewModel(Mission mission):base(mission)
{
MissionVM = new MissionViewModel(mission);
PlatformsVM = new PlatformsViewModel(mission);
PrimaryNetworkVM = new NetworkViewModel(mission, mission.PrimaryNetwork);
//AlternateNetworkVM = new NetworkViewModel(mission, mission.AlternateNetwork);
}

我评论了另一个,因为我还不确定如何处理它。用户可能会通过复选框指示他们想要一个,但应用程序也将用于显示现有数据,因此需要确定是否存在备用数据。对此还不太确定。

我正在处理NetworkViewModel中的NetworkPlatforms,它们是一个可观察的集合,如下所示:

private ObservableCollection<NetworkPlatform> networkPlatforms;
public ObservableCollection<NetworkPlatform> NetworkPlatforms
{
get
{
    if (networkPlatforms == null)
    {
          networkPlatforms = new ObservableCollection<NetworkPlatform>(Network.NetworkPlatforms);
    }
        return networkPlatforms;
    }
}
}

我显然需要编写一些方法来添加和删除该集合中的NetworkPlatform。 我的平台是PlatformsViewModel中的一个可观察集合。我有一个数字微调器供用户指定平台数量和一个函数,它将添加新的或删除最后的x个像这样:

private void ResyncPlatforms(int newValue)
    {
        int oldValue = this.Platforms.Count;
        int diff = newValue - oldValue;
        if (diff > 0)
        {
            for (var i = 0; i < diff; i++)
            {
                var newPlatform = new Platform();
                newPlatform.Mission = Mission;
                this.Platforms.Add(newPlatform);
                missionRepository.AddPlatformToMission(Mission, newPlatform);//TODO need to tell the Network VM to add a network platform
            }
        }
        else
        {
            for (var i = 0; i > diff; i--)
            {
                var platToRemove = Platforms.Last();
                this.Platforms.Remove(platToRemove);
                missionRepository.RemovePlatformFromMission(Mission, platToRemove);//TODO need to tell the Network VM to remove network platform
            }
        }
    }

存储库是一个包含LINQToSQL后端的CRUD选项的包装器。 Add ...和Remove ...方法告诉数据库在提交时插入/删除(当用户保存时)。

那么当PlatformsVM在resync方法中添加/删除平台时,如何让NetworkVM添加/删除NetworkPlatforms?

我知道我可以让我的Resync函数调用我的NetworkViewModel中的方法,这些方法将添加和删除网络平台的集合,当用户打开或关闭备用网络时,我可能会在伞形视图模型中做类似的事情。但我认为必须有一个更好的方法,因为这样做我的平台VM需要访问NetworkviewModel的主要和备用(如果它存在)网络,我不能真正看到如何做备用网络打开和关闭。

让我的networkviewmodel监听PlatformVM的Platforms可观察集合的更改会更好吗?如果是这样的话?

我不清楚该怎么做,并会感谢一些帮助。感谢。

2 个答案:

答案 0 :(得分:1)

我很抱歉,但我真的无法完全按照你的意愿行事。有什么方法可以让它更简洁一点吗?

  

让我的networkviewmodel监听更改会更好吗?   PlatformVM的平台可观察集合,如果是这样的话?

现在我可以回答。 ObservableCollection是可以观察到的。当添加和删除内容时,它将发出CollectionChanged事件,因此只需订阅该事件并做出相应的反应:

private void SubscribeToPlatformChanges()
{
    ((INotifyCollectionChanged)_PlatformVM.Platforms).CollectionChanged += (s, e) =>
    {
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:   //platforms were added - use e.NewItems
            case NotifyCollectionChangedAction.Add:   //platforms were removed - use e.OldItems
            case NotifyCollectionChangedAction.Reset: //all platforms were removed
        }
    }
}

答案 1 :(得分:1)

正确,最好用.NET中的观察者模式处理事件系统。你可以:

  • PlatformsViewModel添加新活动(想想PlatformAdded&amp; PlatformRemoved
  • 或使用ObservableCollection
  • 上的现有内容

这两种方法的区别在于,在第二种方法中,您的NetworkViewModel将更加耦合到PlatformsViewModel - 即。它需要知道它如何存储平台,并且这个存储是可观察的集合,它可能需要处理哪些事件。

请注意,如果您的聚合视图模型(MissionFullDataViewModel)在此通信过程中作为一种人参与,则可能会部分减轻这种情况,因为 - 它将订阅PVM可观察集合的事件并调用NVM方法对此的回应。

无论哪种方式,您都应该使用聚合视图模型来绑定这两个对象,例如:

public MissionFullDataViewModel(Mission mission):base(mission)
{
     MissionVM = new MissionViewModel(mission);
     PlatformsVM = new PlatformsViewModel(mission);
     PrimaryNetworkVM = new NetworkViewModel(mission, mission.PrimaryNetwork);

     // #1: direct binding -- tightly coupled
     PlatformsVM.Platforms.CollectionChanged += NetworkVM.PlatformsChangedHandler;
     // #2: direct binding -- less tightly coupled
     PlatformsVM.PlatformAdded += NetworkVM.PlatformsChangedHandler;
     PlatformsVM.PlatformRemoved += NetworkVM.PlatformsChangedHandler;
     // #3: indirect binding -- less tightly coupled
     PlatformsVM.Platforms.CollectionChanged += this.HandlePlatformsChange;
     // #4: indirect binding -- loosely coupled
     PlatformsVM.PlatformAdded += this.HandlePlaftormsChange;
     PlatformsVM.PlatformRemoved += this.HandlePlatformsChange;
}

HandlePlatformsChange用作中介模式实用程序;它可能会准备来自PlatformsVM事件的数据,然后才会在NetworkVM上调用适当的方法。

在最后一个场景中,没有人知道任何事情 - 只需执行任务所需的数据。这是我建议的方法。平台和网络不需要彼此了解太多,耦合逻辑由知道这两种方式的实体执行 - MissionFullDataViewModel