【问题标题】:How to raise an event in a ViewModel from within a subview's ViewModel如何从子视图的 ViewModel 中引发 ViewModel 中的事件
【发布时间】:2019-06-21 14:11:04
【问题描述】:

我有一个包含多个子视图的主视图的应用程序。这些视图有一个相应的 ViewModel,用于显示模型中包含的一些数据和监控事件。

假设主视图如下所示:

<UserControl x:Class="MyView" Name="myView">
    <StackPanel>
        <local:MySubView Name="mySubView" someProperty="{Binding DataContext.someField, ElementName=myView}"/>
        [...]
    </StackPanel>
</UserControl>

子视图如下所示:

<UserControl x:Class="MySubView"
             prism:ViewModelLocator.AutoWireViewModel="True">
    [...]
</UserControl>

然后在 MySubViewModel.cs 中,发生了一些事件并使用参数调用了一个函数:

public Event EventHandler<SomeClass> MySubViewEvent;
[...]
void foo() {
    SomeClass o = new SomeClass(...);
    MySubViewEvent.Invoke(this, o);
}

现在,在 MyViewModel.cs 中,我没有直接引用子视图,因此不能说类似

subViewModel.MySubViewEvent += OnSubViewEvent;

void OnSubViewEvent(object sender, SomeClass param) { ... }

我可以向 MySubViewModel 添加一些属性,并使其依赖于具有依赖属性的 MyViewModel 中的某些字段,但是 1. 我怎样才能反过来这样做,以便在 MyViewModel 中调用某些回调或事件处理程序时事件在 MySubViewModel 中引发,以及 2. 我可以以某种方式将事件处理程序作为依赖属性传递吗?

或者我应该为此使用 DependencyProperties 以外的其他东西吗?

实现这一目标的最有效方法是什么?

【问题讨论】:

  • 1) 子视图中发生了什么样的事件? 2) 子视图具有对其视图模型的引用。我会让视图在它自己的视图模型上调用一个方法。然后子视图模型将引发一个事件。子视图模型的父视图模型可以根据需要订阅其自己子视图的事件。
  • @EdPlunkett 1)它通过网络在 SubViewModel 内的集合中的某个模型中接收一些数据 2)“子视图模型的父视图模型可以根据需要订阅其自己的子视图的事件”如何这样做是整个问题。父视图模型没有直接引用其子视图模型,因为子视图模型自动连接到子视图
  • 什么接收数据,视图模型还是视图?这整个情况说明了为什么视图优先设计是一个糟糕的主意。如果你不能修复设计,我想你需要某种 Rube Goldberg Locator kludge。您为将一些构造函数调用从一个类转移到另一个类的可疑好处付出了高昂的代价。
  • @EdPlunkett 我不明白你的意思?模型从网络接收数据。然后将其添加到 Viewmodel 中的集合中,并显示在 View 中。就我而言,我有两个子视图模型;一个显示来自网络的数据,另一个显示来自数据库的数据。我想保持网络逻辑和数据库逻辑分开;这就是为什么我把它们做成不同的子视图。但是,现在我想在网络上发生某些事情时更新数据库视图。你会提出什么样的设计?
  • 好吧,也许我有点不清楚,我只是包含了 Prism 标签,但没有在问题中指定它。至少你让我意识到这种方式不是默认方式,而是在 Prism 库中解耦代码的特定方式。这并没有真正浪费我的时间。

标签: c# wpf mvvm prism


【解决方案1】:

使用EventAggregator 的教科书示例,尽管我应该补充一点,子视图模型也是视图模型优先的教科书示例。 ViewModelLocator 对于独立的顶级视图最有用...

话虽如此,在子视图模型中:

_eventAggregator.GetEvent<MySubViewEvent>().Publish();

其他地方:

public MainViewModel( IEventAggregator eventAggregator )
{
    eventAggregator.GetEvent<MySubViewEvent>().Subscribe( OnSubViewEvent );
}

【讨论】:

  • 我完全忘记了 EventAggregator!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-04
相关资源
最近更新 更多