【问题标题】:Updating other ViewModels and Container form from a PropertyChanged command in one of the UserControls in WPF从 WPF 中的用户控件之一中的 PropertyChanged 命令更新其他 ViewModel 和容器表单
【发布时间】:2013-08-30 08:03:23
【问题描述】:

我有一个 WPF Window 和一组用户控件,每个控件都有自己的视图模型。在容器 Window 的 ViewModel 上,我有他们的 ViewModel 的实例。

在其中一个 UserControls 中有一个 ComboBox,在其 SelectionChanged 上,我需要更新其他 UserControls 以及容器 Window(即它们对应的 ViewModel)。

我试图放弃为这些用户控件使用 ViewModel 的想法,而是将它们的功能放在容器表单的 ViewModel 上,但这似乎并不正确,因为用户控件实际上做了很多事情,而且拥有起来非常复杂容器窗口的 ViewModel 上的所有内容。

有什么方法可以实现这一点,还是我应该使用“容器窗口的 ViewModel 上的所有内容”?

非常感谢任何帮助。

【问题讨论】:

  • 提示:使用任何类型的事件聚合器/消息总线来解耦消息...
  • @PatrykĆwiek 你能指点我一些例子吗?
  • 您可以为此制作模型。所以你得到事件改变模型中的一些属性,其他视图模型依赖于模型中的这个属性
  • 当然:firstsecondthirdfourth 链接。

标签: c# wpf xaml mvvm user-controls


【解决方案1】:

您可以使用delegates 轻松实现您想要的(每个控件都有一个视图模型)。您可以从 MSDN 上的 Delegates (C# Programming Guide) 页面了解有关 delegates 的更多信息。

基本上,您需要在您的 UserControl 对象中创建一个或多个 delegates...它们非常适合将信息从父母传递给孩子,反之亦然:

public delegate void ParentNotification(YourDataType dataTypeInstance);

然后是一个 getter 一个 setter:

public ParentNotification OnSelectionChanged { get; set; }

现在实例化UserControl 的窗口可以为这些委托中的每一个注册一个处理程序:

<YourXmlNamespace:YourUserControl OnSelectionChanged="OnSelectionChangedhandler" />

然后在MainWindow.xaml.cs中添加一个与delegate的定义相匹配的处理程序:

public void OnSelectionChangedhandler(YourDataType dataTypeInstance)
{
    // do something with dataTypeInstance
}

难题的最后一部分是在任何条件发生后从每个UserControl 调用delegate...在这种情况下,条件是选择发生了变化:

private void ComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    YourDataType dataTypeInstance = null;
    if (e.AddedItems.Count > 0) 
    {
        dataTypeInstance = (YourDataType)e.AddedItems[0];
        if (OnSelectionChanged != null) // very important check here
        {
            OnSelectionChanged(dataTypeInstance);
        }
    }
}

【讨论】:

  • 不会提出这种方法。 (The final piece of the puzzle is to call the delegate from each UserControl after whatever condition has occurred) 让 View 评估这些条件 会破坏测试能力,从而失去能够对几乎所有相关逻辑进行单元测试的一些 MVVM 优势。通过使用 messenger/eventaggregator,UI 逻辑被保存在它所属的位置(在 VM 中),并且该数据的同步可以直接在 VM 之间进行,而无需 Views 的参与。
  • 嘿@Viv,虽然我同意你的观点,但问题作者明确表示他在UserControl 中使用了SelectionChanged 事件。这是他的选择,所以告诉他吧。
  • 我在此处添加评论之前也是如此。问题作者几乎总是根据他们知道或知道/喜欢的内容提出问题。我的评论不是试图表明你正在做的事情是“错误的”(如果是这样,我会投反对票),而是要确保将来其他任何人只要看看这个答案就知道有其他方法可以解决这个问题整个问题,并通过这样做产生一些好处。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多