我正在使用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可观察集合的更改会更好吗?如果是这样的话?
我不清楚该怎么做,并会感谢一些帮助。感谢。
答案 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
。