【问题标题】:Passing property from one "view" to other view's viewmodel in MVVM将属性从一个“视图”传递到 MVVM 中其他视图的视图模型
【发布时间】:2011-10-22 11:06:14
【问题描述】:

我是 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 是用户控件,位于父级上,由ChildView 表示。 代码很丑,所以我希望在不破坏模式方面看到更好的实践。 谢谢。

【问题讨论】:

  • @Mario Vernari,我试图描述的事情的正确方法是什么。

标签: .net wpf mvvm design-patterns


【解决方案1】:

是的 - 这段代码非常难看。事实上,我正在努力弄清楚它到底做了什么!

MVVM 模式的主要租户之一是 ViewModel 应该是可单元测试的,并且应该可以在没有视图的情况下执行它。遇到此类问题时,只考虑视图模型,忽略视图。

您的 ParentViewModel 具有对 ChildViewModel 的引用,您可以通过在创建 ChildViewModel 时让 ParentViewModel 提供对自身的引用来建立这种双向关系。这意味着您可以从 ChildViewModel 执行 ParentViewModel 上的任何公共方法。

考虑到这一点,您应该能够解决您的问题!

(另外,您不应该在依赖属性的 getter 或 setter 中添加逻辑,此代码可能会或可能不会被调用,具体取决于您的依赖属性值的设置方式。)

【讨论】:

  • 嗯,好建议!当然,我可以创建父级的接口并将该接口类型的引用传递给子级(我可以为该子级设置许多“不同”的父级用户控件)。谢谢,我试试。我认为仅考虑 ViewModel 的建议是最好的。当然它必须在没有 View 的情况下工作。
  • 是的,向 ChildViewModel 传递一个只有应该能够调用的方法的接口听起来是个好主意。
  • 孩子永远不应该知道谁是他们的父母,但父母知道。如果你想从任何后代向上“交流”某些东西,你应该使用命令。这允许在没有任何耦合的情况下向祖先交换数据。
  • @MarioVernari 我强烈反对!如果您有一个具有父 => 子关系的 OrderViewModel 和 OrderLineViewModel,那么它们紧密耦合并且关系是双向的并没有错。你想在任何其他上下文中使用 OrderViewModel 吗?不!当然,一个命令可能会让你觉得你在使用更优雅的代码,但是在视图模型中从子级到父级的直接调用要简单得多,也更容易理解。
  • 也许我不明白这个问题/问题,但如果你正在耦合两个 VM,我也同意这是完全正确的。在上面的问题中,这个人指的是一个视图和一个视图模型......要么我无法正确阅读,要么我会保持分离。完全尊重任何其他观点!
【解决方案2】:

不要在 DependencyProperty 的 setter 或 getter 中编写任何逻辑,因为它是由框架以其他方式调用的,而不是直接通过 set/get 访问器。这是必须的规则。

也是字符串

((ChildViewModel)this.DataContext).CallbackAction = value; 

在当前 View 和底层 ViewModel 类型之间引入了绑定耦合,这不是 MVVM 原则。

在 View 依赖的情况下,您应该考虑使用 XAML 中的绑定传递属性,否则 ParentViewModel 应该通过构造函数注入 ChildViewModel。所以他们应该被设计成表明 ParentViewModel 有一个 Child...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    • 2017-10-04
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    相关资源
    最近更新 更多