在我的应用程序模型中,我有一个“ parent ”列表,每个“ parent ”都引用一个“ child ”列表(例如,一个足球队列表,每个球队都包含一个球员列表)。
我在 TreeView 中可视化此列表。我为树创建了一个 View 模型类,为足球队创建了一个 View 模型类(我们称之为“footballteamViewModel”)。树的类包含一个带有 footballteamViewModel-items 的 ObservableCollection。树的项目源是这个 ObservableCollection。在初始化期间,我为模型中的每个足球队创建一个相应的 footballteamViewModel 对象并将其添加到 ObservableCollection。
问题是,我的模型中的足球队列表可以从树的外部更改,我希望更新树。因此,如果有人从我的模型列表中删除了一个足球队,我将不得不在我的 footballteamViewModel-items 的 ObservableCollection 中删除相应的项目。
我无法将模型中的足球队列表直接绑定(bind)到 View 。因此,每次更改模型中的集合时,我都必须以某种方式更新 ViewModel 中的 ObservableCollection。
我处理这个问题的方法是在模型中使用 ObservableCollection 并注册到 ViewModel 中的 collectionChanged 事件,以便在模型集合发生更改时更新我的 ViewModel(footballteamViewModel 对象的 Observable 集合)。但这感觉不“对”。有没有更好的办法?
在输入此内容时,我发现了另一篇描述完全相同问题的帖子:WPF/MVVM: Delegating a domain Model collection to a ViewModel .那里的答案鼓励我,我解决这个问题的方式并不是完全错误的,但我仍然想知道是否还有另一种方法。
编辑:根据您提供的第一个答案,我认为我的问题没有明确的答案。他们都很有帮助,所以值得一读。我只引用 Bindable Linq/Continous Linq/Optics 框架来标记答案,因为我认为这会帮助其他最容易被我的问题绊倒的人。
最佳答案
这是 MVVM 最讨厌的地方之一。
我刚才做的一件事是创建一个 ViewModelCollection<T>
继承ObservableCollection<T>
并具有修改器方法(添加、删除),对两个集合执行操作,如下所示:
public interface IViewModel<T>
{
T WrappedModel { get; }
}
public class ViewModelCollection<T,M> : ObservableCollection<T,M> where T : IViewModel<M>
{
private IList<M> _baseCollection;
public ViewModelCollection(IList<T> baseCollection)
{
_baseCollection = baseCollection;
}
public override void Add(T objectToAdd)
{
IViewModel<M> vm = objectToAdd as IViewModel<M>;
if (vm != null)
{
this.Add(objectToAdd);
_baseCollection.Add(vm.WrappedModel);
}
}
public override void Remove(T objectToRemove)
{
IViewModel<M> vm = objectToRemoveas IViewModel<M>;
if (vm != null)
{
this.Remove(objectToRemove);
_baseCollection.Remove(vm.WrappedModel);
}
}
}
现在我根本不这样做,我只是使用 CaSTLe Proxies 将 INotifyPropertyChanged 功能添加到我的模型中 - 节省了大量样板代码!
请注意,我没有测试代码,只是凭内存输入。
关于wpf - 集合和父/子关系的 MVVM 概念,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10445660/