基于 WPF 和 MVVM 模式中的嵌套模型实体构建 ViewModel
我在理解如何基于以下模型构建视图模型时遇到问题
(我简化了模型以使其更清晰)
public class Hit
{
public bool On { get; set;}
public Track Track { get; set; }
}
public class Track
{
public ObservableCollection<Hit> Hits { get; set; }
public LinearGradientBrush Color { get; set; }
public Pattern Pattern { get; set; }
}
public class Pattern
{
public string Name { get; set; }
public ObservableCollection<Tracks> Tracks { get; set; }
}
现在,我的问题是如何构建 ViewModel ..
我需要通过模型保留原始关系,因为我Pattern 上有一个 Serialize() 方法,将其序列化为 XML 文件。(带有相关的 Tracks 和 Hits)
为了能够将模式绑定到用户控件及其嵌套模板,我还应该有一个带有 ObservableCollection< 的 PatternViewModel ;TrackViewModel>其中,TrackViewModel 和 HitViewModel 也是如此。我需要在不属于业务对象的视图模型上拥有自定义表示属性(颜色等)。
这对我来说似乎不是一件好事复制视图模型上模型的所有关系... 并且在编码视图模型时跟踪所有这些关系也更容易出错..
有人有更好的方法/解决方案吗?
I have a problem understanding how to build view models based on the following models
(I simplified the models to be clearer)
public class Hit
{
public bool On { get; set;}
public Track Track { get; set; }
}
public class Track
{
public ObservableCollection<Hit> Hits { get; set; }
public LinearGradientBrush Color { get; set; }
public Pattern Pattern { get; set; }
}
public class Pattern
{
public string Name { get; set; }
public ObservableCollection<Tracks> Tracks { get; set; }
}
Now, my problem is, how to build the ViewModels..
I need to keep the original relationships through the models, beacaus i have a Serialize() method on the Pattern that serializes it to an XML file.. (with the related Tracks and Hits)
To be able to bind the pattern to the user controls and it's nested templates I should also have a PatternViewModel with an ObservableCollection<TrackViewModel> in it, same thing for the TrackViewModel and the HitViewModel.. and i neet to have custom presentation properties on the view models that aren't part of the business object (colors and more..)
It just seem not a good thing to me to duplicate all of the relationships of the models on the view models...
and keeping track of all this relations while coding the viewmodels is also much more error prone..
anyone has a better approach/solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我做过的一件事(并取得了一些成功)是将 ObservableCollection 移出模型。这是我的一般模式:
List
作为后备集合,而不是 ObservableCollection。ObservableCollection
。这会为每个不同的 ViewModel 带来大量重复的代码,但这是我能想到的最好的。它至少可以根据您需要的复杂性进行扩展——如果您有一个仅添加的集合,则无需编写太多代码;如果你有一个支持任意重新排序、插入、排序等的集合,那么工作量就大得多。
One thing I've done, with some success, is to move the ObservableCollection out of the model. Here's my general pattern:
IEnumerable<TModel>
that gives read-only access to the collection. Use a plain oldList<TModel>
, not an ObservableCollection, as the backing collection.ObservableCollection<TNestedViewModel>
.This makes for a lot of duplicate code for each different ViewModel, but it's the best I've been able to come up with. It does at least scale based on the complexity you need -- if you have a collection that's add-only, you don't have to write much code; if you have a collection that supports arbitrary reordering, inserts, sorting, etc., it's much more work.
我最终使用了 Joe White 建议的解决方案的一部分,但方式略有不同
解决方案是将模型保留在开始时的样子,并将内部集合的 CollectionChanged 的事件处理程序附加到集合,例如, PatternViewModel 将是:
所以我可以在视图模型上附加新的颜色/样式/命令,以保持我的基本模型干净
每当我添加/删除/移动基本模型集合中的项目时,视图模型集合与每个模型保持同步其他
幸运的是,我不必在应用程序中管理大量对象,因此重复的数据和性能不会成为问题,
我不太喜欢它,但它运行良好,而且工作量也不是很大,只是包含其他视图模型集合的视图模型的事件处理程序(在我的例子中,一个用于 PatternViewModel 来同步 TrackViewModels,另一个用于 TrackViewModel 来管理 HitViewModels)
仍然对您的想法或更好的想法感兴趣 =)
I ended up using part of the solution that Joe White suggested, in a slighty differ manner
The solution was to just leave the models as they were at the beginning, and attaching to the collections an eventhandler for CollectionChanged of the inner collections, for example, the PatternViewModel would be:
So i can attach the new Color/Style/Command on the view models to keep my base models clean
And whenever I add/remove/move items in the base models collection, the view models collections remain in sync with each other
Luckily I don't have to manage lots of object in my application, so duplicated data and performance won't be a problem
I don't like it too much, but it works well, and it's not a huge amount of work, just an event handler for the view model that contains others view model collections (in my case, one for PatternViewModel to sync TrackViewModels and another on TrackViewModel to manage HitViewModels)
Still interested in your thoughs or better ideas =)
我想我也有同样的问题,如果你像“PatternViewModel with an ObservableCollection”那样做由于开始复制数据,您的性能也会受到巨大影响。
我的方法是为您的示例构建一个具有 ObservableCollection
I think I had the same problem and if you do it like "PatternViewModel with an ObservableCollection<TrackViewModel>" you also get a massive impact on your performance because you start duplicating data.
My approach was to build - for your expample - a PatternViewModel with a ObservableCollection<Track>. It's no contradiction to MVVM because the view is bound to the collection.
This way you may avoid the duplication of the relationships.
我一直在考虑的一种解决方案是使用转换器围绕模型创建视图模型,尽管我不确定它在实践中是否能完美工作。
因此,在您的情况下,您可以将
Tracks
直接绑定到(作为示例)列表框,并使用从 Track 创建新的TrackViewModel
的转换器。您的所有控件将看到的是一个TrackViewModel
对象,而您的所有模型将看到的是其他模型。不过我不确定这个想法的动态更新,我还没有尝试过。
One solution I've been considering, although I'm not sure if it would work perfectly in practice, is to use converters to create a viewmodel around your model.
So in your case, you could bind
Tracks
directly to (as an example) a listbox, with a converter that creates a newTrackViewModel
from the Track. All your control would ever see would be aTrackViewModel
object, and all your models will ever see is other models.I'm not sure about the dynamic updating of this idea though, I've not tried it out yet.