2010-07-15 109 views
0

现在我搜索了两个多星期的答案。这通常意味着我是盲人或者这个想法是荒谬的。不管怎么说:C#MVVM TreeView双向绑定的分层数据

在一个中等规模的,相当灵活的项目中,我存储配置数据的分层结构在这样一个的:

  • 配置(集合)
    1. 音频(类)
      • 的BaseDir(结构)
      • PLAYMODE(枚举)
      • 输入(类)
      • CalibrateOnConnect(布尔)
      • KnownDevices(集合)
        1. ...(类)
          • ...
      • UseDevice(整数)
      • 播放列表(收藏)
        1. FirstAudio(类)
          • 路径(串)
          • 重复(整数)
      • ...

我已经管理显示y这些在MVVM模式中的TreeView中。因为我不能确切地告诉哪些选项将在未来被添加,我用了一个通用的方法,用于创建的ViewModels classienumerable,我的自定义structs和基本的值类型(stringboolenum,...)。

在我的XAML中,它们具有它们相应的(分层的)数据模板,例如,一个用于布尔值的CheckBox或一个用于常规值类型的文本块。

每个ViewModel实例都有一个字段来存储基础模型的数据。

我设法在View中编辑这些值,并通过ViewModel中的TwoWay-Binding来编辑这些值。
但是,让我头疼的是如何更新模型中的这些数据。
由于我通过反射创建了分层ViewModel结构,因此父级没有与等效配置类/集合的字段名称/索引器/ ...相对应的get/set属性。尽管每个ViewModel实例都知道父级模型的数据结构的字段/属性名称,但是该父级模型的数据结构是从其父级ViewModel实例创建的,并且也知道它的父级模型实例。
通过命令或通过调用父母的某个更新函数来解决此问题的每一次尝试都为我的大脑注入了活力。

是否有通过常规绑定技术实现这一点的简单方法?
如果我为每个正在使用的配置(子)类创建ViewModels会更好吗?
提示:每个ViewModel实例都知道父级模型数据结构中的字段/属性名称。

+0

通过为'string','bool','enum','ienumerable',*等创建视图模型,你获得了什么?为什么不直接绑定到这些?如果视图模型不知道如何操作模型,那么我根本不会认为它是一个视图模型。 – Jay 2010-07-15 17:07:04

+0

由于类的ViewModel不知道它包含哪些确切的字段,因此任何类的TreeViewItem都包含每个字段和参数的子项,这些子项可能本身又是一个类。 从C++中思考我会使用一些引用来存储指向该字段的“指针”(正在特定ViewModel的构造函数调用中访问)。 – 2010-07-16 07:03:08

+0

我现在明白,没有像“通用ViewModel”这样的东西,我认为这很让人伤心。相反,对于任何Model类,必须有一个特定的ViewModel和一个特定的View。 – 2010-07-27 13:36:02

回答

1

通读评论我认为,视图模型应该紧密耦合到它试图表示的模型。拥有动态视图模型也很难测试。但是,如果您真的想尝试解决这个问题,可以考虑使用DynamicObject,它允许您以完全通用的方式获取/设置实例的属性。通过DynamicObjects,您可以获得在设置或获取属性时调用的钩子,这可以使您(例如)为给定的动态属性引发NotifyPropertyChange事件。