【问题标题】:MVVM with a tree of models带有模型树的 MVVM
【发布时间】:2013-10-23 07:50:03
【问题描述】:

我有一个应用程序,其中包含构成一种模式的模型对象树。这可能看起来像:

ElementSet
....ElementGroup
........ScalarElement
........BoolElement
....ElementGroup
........MatrixElement
........VectorElement

这棵树要复杂得多,但你明白了。我将在 WPF TreeView 中显示这棵树,允许用户不仅选择特定节点(主从样式),还可以添加、删除和重新排列节点。

我的意图是将树中的每个节点封装在一个 ViewModel 中,我将在其中添加命令、工具提示信息和其他与 ViewModel 相关的绒毛。

我的问题在于我有一棵模型树,并且真的需要一棵 ViewModels 来配合它。我正在努力想一个优雅的解决方案。我该如何构建这个?让它们保持同步?等等

我正在玩弄的一个想法是将视图直接绑定到模型对象的图形,但使用 ValueConverter 将模型转换为每个节点上的 ViewModel。每个模型都有一个唯一的 ID,因此让转换器维护 ViewModel 的可查询缓存以返回视图并不是不可能的。

还有哪些其他有效的策略可以为模型集合/树创建视图模型?

【问题讨论】:

    标签: wpf mvvm


    【解决方案1】:

    根据数据的复杂性,我建议为每个元素使用一个 View 模型和一个构造函数,该构造函数将从您的模型递归地构建一棵树。

    如果您只是想从模型中显示字符串和格式化的双精度数,您甚至可能不需要视图模型,但从长远来看,它会让您的系统更加灵活。

    【讨论】:

      【解决方案2】:

      我最终使用了带有 ViewModel 缓存的 ValueConverter。它实际上工作得很好。我这样设置我的 TreeView:

      <TreeView ItemsSource="{Binding TreeRoot}">
          <TreeView.ItemTemplate>
              <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                  <ContentPresenter Content="{Binding Converter={StaticResource ModelToViewModelConverter}}"/>
              </HierarchicalDataTemplate>
          </TreeView.ItemTemplate>
      </TreeView>
      

      ...其中 TreeRoot 是模型对象树的根,每个对象都有一个属性“Children”。并像这样创建了我的转换器:

      public class ModelToViewModelConverter : IValueConverter
      {
          private static Dictionary<Guid, ViewModelBase>  _map = new Dictionary<Guid, ViewModelBase>();
      
          public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
          {
              var element = value as ElementBase;
      
              if (!_map.ContainsKey(element.Id))
              {
                  if (element is ElementSet)_map.Add(element.Id, new ElementSetViewModel(value as ElementSet));
                  if (element is ElementGroup) _map.Add(element.Id, new ElementGroupViewModel(value as ElementGroup));
                  if (element is StringElement) _map.Add(element.Id, new StringElementViewModel(value as StringElement));
                  if (element is ScalarElement) _map.Add(element.Id, new ScalarElementViewModel(value as ScalarElement));
              }
      
              return _map[element.Id];
          }
      
          public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
          {
              //A change.sdfsdfdsff
              throw new NotImplementedException();
          }
      }
      

      这允许我只维护一棵模型对象树,但允许我使用 ViewModels 来绑定视图。

      【讨论】:

        猜你喜欢
        • 2010-11-28
        • 1970-01-01
        • 1970-01-01
        • 2012-12-27
        • 1970-01-01
        • 1970-01-01
        • 2014-03-25
        • 1970-01-01
        • 2017-05-18
        相关资源
        最近更新 更多