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
}
不要忘记处理更改的事件
我有这样的树结构:
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
}
不要忘记处理更改的事件