将属性从一个“视图”传递到MVVM中的其他视图的视图模型

时间:2011-08-08 14:35:54

标签: .net wpf mvvm design-patterns

我是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表示。    代码是丑陋的,所以我希望看到更好的实践,不破坏模式。   谢谢。

2 个答案:

答案 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 ...