WPF MVVM 使用视图模型更新模型

WPF MVVM Update Model Using View Model

我有这样的树结构:

public class Node
{
    public Node Parent { get; set; }
    public List<Node> Children { get; set; }
    public NodeValue Item { get; set; }
}

还有一个像这样的 NodeViewModel:

    public class NodeViewModel : INotifyPropertyChanged
    {
    public Node Node
    {
        get;
        private set;
    }
     public NodeViewModel(Node node)
    {
      this.Node = node;
      this._children = new ObservableCollection<NodeViewModel>();
    }

  public string Code { 
      get
      {
          return this.Item.Code;
      }
      set
      {
          this.Item.Code = value;
          NotifyPropertyChanged("Code"); 
      }
           }

  public Node Parent
  {
      get
      {
          return this.Node.Parent;
      }
      set
      {
          if (value != this.Node.Parent)
          {
              this.Node.Parent = value;
              NotifyPropertyChanged("Parent");
          }
      }
  }

  public NodeValue Item 
  {
      get
      {
          return Node.Item; 
      }
      set 
      {
          this.Node.Item = Item;
      } 
  }
private ObservableCollection<NodeViewModel> _children;

public ObservableCollection<NodeViewModel> Children 
  {
      get
      {
          _children.Clear();
         foreach(var child in Node.Children)
         {
             _children.Add(new NodeViewModel(child));
         }
         return _children;
      }
      protected set
      {
          this._children = value;
          NotifyPropertyChanged("Children");
      }
  }

问题是最后一个 属性 因为当我想使用视图模型更新模型时,例如当我想添加一个新节点时我必须更新 _children ObservableCollection来自 NodeViewModel 以及 Children List<Node> 来自 Node class.

如果我只更新模型,UI 不会更新,因为 NotifyPropertyChanged 没有被调用,如果我只更新视图,更改将会丢失,因为 getter将创建另一个 ObservableCollection 并且更改不会反映在模型上。

如何通过视图模型更新模型class?

无论以何种方式切片,视图模型都需要完全封装模型。如果你有一个 "save" 命令,你可以 update/recreate 当时模型的集合。

假设您没有 "save" 命令,并且模型应该始终反映视图模型的当前状态,一种选择是订阅 ObservableCollection<T>.CollectionChanged 事件并更新动态基础集合。


旁注,您很可能也不希望每次调用 Children_get 时都创建一个新集合,最好只延迟加载一个您保留的集合。

ObservableCollection 已经实现了 INotifyPropertyChanged。 但是,它仅在集合计数发生变化时才有效。 还有为什么你想要一个 ViewModel 集合? 但我认为您正在寻找此实现:

private ObservableCollection<Node> _children;

public ObservableCollection<Node> Children {
  ...code logic
}

不要忘记处理更改的事件