2

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

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

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

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

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

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

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

4

2 回答 2

1

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

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

于 2013-10-23T08:05:56.280 回答
1

我最终使用了带有 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 来绑定视图。

于 2013-10-24T06:58:46.760 回答