我是MVVM的新手并且遇到小问题。我有两个用户控件:父级和子级(带视图,视图模型,模型类)。并且需要将一些属性从父级传递给子级。现在我通过编写这样的代码来管理它:
public static readonly DependencyProperty CallbackActionProperty =
DependencyProperty.Register("CallbackAction", typeof (Action),
typeof (ChildView), new PropertyMetadata(default(Action)));
public Action CallbackAction
{
get { return (Action) GetValue(CallbackActionProperty); }
set
{
SetValue(CallbackActionProperty, value);
((ChildViewModel)this.DataContext).CallbackAction = value; // Change ViewModel property too
}
}
这是ChildView
中的依赖属性,在其集合中我也设置了ViewModel
的属性。之后,我从ParentView
访问该依赖项属性并设置CallbackAction
- >在Child的ViewModel中设置CallbackAction
代码:
this.Loaded += (sender, args) => childUc.CallbackAction = ((ParentViewModel) this.DataContext).RefreshStatuses;
childUc
是usercontrol,位于父级并由ChildView
表示。
代码是丑陋的,所以我希望看到更好的实践,不破坏模式。
谢谢。
答案 0 :(得分:3)
MVVM模式的主要租户之一是ViewModel应该是可单元测试的,并且应该可以在没有视图的情况下执行它。当遇到这种问题时,单独考虑模型并忽略视图。
您的ParentViewModel具有对ChildViewModel的引用,您可以通过让ParentViewModel在创建ChildViewModel时提供对自身的引用来使其成为双向关系。这意味着从ChildViewModel可以在ParentViewModel上执行任何公共方法。
考虑到这一点,你应该能够解决你的问题!
(另外,您不应在依赖项属性getter或setter中添加逻辑,根据您的依赖项属性值的设置方式,可能会调用此代码,也可能不调用此代码。)
答案 1 :(得分:1)
不要在DependencyProperty
的setter或getter中编写任何逻辑,因为它以orher方式由Framework调用,而不是直接通过set / get访问器调用。这是必须的规则。
也是字符串
((ChildViewModel)this.DataContext).CallbackAction = value;
引入了当前View和底层ViewModel类型之间的绑定耦合,这不是MVVM原则。
如果是View依赖项,你应该考虑在XAML中使用绑定传递属性,否则ParentViewModel应该通过构造函数注入一个ChildViewModel。所以它们应该被设计成表明ParentViewModel有一个Child ...