2

我需要以不同的方式呈现一个对象,两次。

  1. 作为 TreeView 中的节点(导航/重命名)
  2. 作为 2 个文本框(重命名/编辑内容)
public class Item
{
    public string Name{get;set;}
    public string Content{get;set;}
}

我的第一个解决方案是保持简单:

public class MainViewModel
{
    // collection of items (treeview navigation)
    public BindingList<ItemViewModel> Items{get;set;}

    // selected item (from treeview navigation)
    // used for textbox edit
    public ItemViewModel SelectedItem{get;set;}
}

public class ItemViewModel
{
    // Used for treeview navigation
    public bool IsSelected{get;set;}
    public bool IsExpanded{get;set;}
    public bool IsInEditNameMode{get;set;}
    public BindingList<ItemViewModel> Children{get;set;}
    public void BuildChildren();

    // Used for treeview display/rename
    // Used for textbox display/rename
    public string Name{get;set;}

    // Used for textbox edit
    public string Content{get;set;}
}

这在一段时间内效果很好。但是随着应用程序变得越来越复杂,视图模型变得越来越“污染”。

例如,为同一个视图模型添加额外的展示(高级属性、图表表示等)

public class ItemViewModel
{
    // Used for Advanced properties
    public BindingList<PropertyEntry> Properties {get;set;}
    public PropertyEntry SelectedProperty{get;set;}

    // Used for graph relationship
    public BindingList<ItemViewModel> GraphSiblings{get;set;}
    public bool IsGraphInEditNameMode{get;set;}
    public bool IsSelectedGraphNode {get;set;}
    public void BuildGraphSiblings();

    // Used for treeview navigation
    public bool IsNavigationInEditNameMode{get;set;}
    public bool IsSelectedNavigationNode{get;set;}
    public bool IsExpandedNavigationNode{get;set;}
    public BindingList<ItemViewModel> NavigationChildren{get;set;}
    public void BuildNavigationChildren();

    // Used for treeview display/rename
    // Used for textbox display/rename
    // Used for graph display
    // Used for Advanced properties display
    public string Name{get;set;}

    // Used for textbox edit
    public string Content{get;set;}
}

目前,我仍在为多个演示文稿使用单个视图模型,因为它使所选项目在所有演示文稿中保持同步。

此外,我不必不断重复属性(名称/内容)。

最后,PropertyChanged 通知有助于更新项目的所有表示(即,更改导航中的名称会更新 TextBox/Graph/Advanced 属性/等)。

然而,它也感觉像是违反了几个原则(单一责任、最小特权等)。

但我不太确定如何重构它,无需编写大量代码来保持同步/属性通知工作/在每个新视图模型/等中复制模型的属性)

我想知道的:

如果由你决定,你会如何解决这个问题?

目前,一切仍在正常工作。我只是觉得代码可以进一步改进,这就是我需要帮助的地方。

4

2 回答 2

1

如何使用继承?拥有一个 basic ItemViewModel,然后将其子类化以创建一个TreeViewItemViewModel,您可以在其中添加与子类中此项的树视图呈现相关的属性。

于 2013-01-07T09:30:02.903 回答
0

我们能,

  1. 尝试从 ItemViewModel 类中分离出各种特定于视图的行为。
  2. 在单独的类(行为类)中放置/封装视图特定的行为。

这使您可以在运行时灵活地实例化/注入/切换行为。是的,尝试使用策略模式来制作更简洁、单一负责、易于维护的代码。

于 2013-01-07T11:00:38.420 回答