在我的应用程序的模型中,我有一个“父母”列表,每个“父母”都列出一个“孩子”列表(例如,每个包含一个玩家列表的足球队列表) .
我在树视图中可视化此列表 . 我为树创建了一个viewmodel-class,为footballteam创建了一个viewmodel-class(让我们称之为“footballteamViewModel”) . 树的类包含一个带有footballteamViewModel-items的ObservableCollection . 树的items-source是ObservableCollection . 在初始化期间,我为模型中的每个足球队员创建一个相应的footballteamViewModel对象,并将其添加到ObservableCollection中 .
问题是,我的模型中的足球队列表可以从树外部更改,我希望更新树 . 因此,如果有人从我的模型中的列表中删除了一个足球队,我将不得不删除我的足球队观察队列的ObservableCollection中的相应项目 .
我无法将模型中的足球队列表直接绑定到视图中 . 因此,每次更改模型中的集合时,我都必须以某种方式更新ViewModel中的ObservableCollection .
我处理这个问题的方法是在模型中使用ObservableCollection并注册到ViewModel中的collectionChanged-event,这样我就可以在更改模型集合时更新我的ViewModel(footballteamViewModel对象的Observable集合) . 但这感觉并不“正确” . 有没有更好的办法?
在键入此内容时,我发现另一篇文章描述了完全相同的问题:WPF/MVVM: Delegating a domain Model collection to a ViewModel . 那里的答案鼓励我,我解决这个问题的方式并非完全错误,但我仍然想知道是否还有其他方法 .
编辑:从你提供的第一个答案我认为我的问题没有明确的答案 . 他们都很有帮助,所以值得一读 . 我只是通过引用Bindable Linq / Continous Linq / Optics框架来标记答案,因为我认为这将有助于其他最能绊倒我的问题的人 .
4 回答
您的解决方案完全没有错,但有一些库可以帮助您更轻松地实现它,如BindableLinq,ContinuousLinq或Obtics . 你对他们有一个错觉here . 可悲的是,他们似乎都没有进一步发展 .
我对Clinq的个人经历非常好,我仍然使用它,应该适合您的情况 .
这是MVVM中比较讨厌的地方之一 .
我之前做过的一件事就是创建一个
ViewModelCollection<T>
,它继承ObservableCollection<T>
并具有修改方法(Add,Remove),它们对两个集合执行操作,如下所示:到目前为止我根本不这样做,我只使用Castle Proxies将INotifyPropertyChanged功能添加到我的模型中 - 节省了大量的样板代码!
请注意,我还没有测试过代码,只是从内存中输入了代码 .
您说您无法将模型集合直接绑定到视图(这意味着视图模型需要使用模型集合包含的副本创建自己的
ObservableCollection
),此外视图需要在模型集合时实时更新更改(这意味着模型需要通知viewmodel此类更改,并且viewmodel需要更新其内部副本) .所有这些都不是一个读/写
IEnumerable
,在这种情况下,只要需要修改集合,模型的使用者就会被迫用新实例交换它 . 作为回报,可以简化viewmodel的"stay in sync"代码,并且可以通过集合属性上的INotifyPropertyChanged
触发同步 .晚了,但可能有助于其他人...
阅读这篇关于这个主题的优秀3部分博客文章系列 .
第3部分是关于收藏并展示了一些解决方案 - 帮助了我很多
MVVM: To Wrap or Not to Wrap? How much should the ViewModel wrap the Model?