1

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

我有一种用于任务的伞视图模型,它实例化一些像这样的子视图模型

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,它们是这样的 observablecollection:

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 在重新同步方法中添加/删除平台时,如何让我的 NetworkVM 添加/删除 NetworkPlatforms?

我知道我可以让我的 Resync 函数调用 NetworkViewModel 中的方法,这将添加和删除 networkplatforms 它的集合,并且当用户打开或关闭备用网络时,我可能会在伞形视图模型中执行类似的操作。但我认为必须有更好的方法,因为这样做我的 Platforms VM 需要访问主要和备用(如果存在)网络的 NetworkviewModels,而当备用网络时我真的不知道该怎么做网络打开和关闭。

让我的networkviewmodel监听PlatformVM的Platforms observable集合的变化会更好吗?如果是的话怎么做?

我不太清楚该怎么做,希望能得到一些帮助。谢谢。

4

2 回答 2

1

很抱歉,但我真的无法完全按照您的要求进行操作。有什么办法可以让它更简洁一点吗?

让我的networkviewmodel监听PlatformVM的Platforms observable集合的变化会更好吗?如果是的话怎么做?

现在这个我可以回答了。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
        }
    }
}
于 2012-04-27T12:53:38.177 回答
1

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

  • PlatformsViewModel向(think PlatformAdded& PlatformRemoved)添加新事件
  • 或使用现有的ObservableCollection

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

请注意,如果您的聚合视图模型MissionFullDataViewModel

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

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

In the last scenario, nobody knows anything - just the required data to perform task. And this is approach I'd suggest. Platforms and Networks don't need to know much about one another and coupling logic is performed by entity that knows about those two either way - MissionFullDataViewModel.

于 2012-04-27T13:03:27.727 回答