c# - 使用 Prism 事件聚合器从代码隐藏到视图模型进行通信
问题描述
我正在使用 MVVM 模式开发 WPF 应用程序。此外,我一直在利用 Prism 事件聚合器功能在视图模型之间进行通信。
我们正在使用一个控件库,并且我们正在使用的其中一个控件(更改/自定义的数据网格)具有库作者创建的事件。例如,当一个单元格结束编辑时......类似于丢失焦点。我面临的问题是库控件利用背后的代码而不是事件方法的视图模型。
我想我会简单地利用事件聚合器让 VM 从后面的代码中了解事件。它不工作。我的虚拟机在构造函数中使用了一个简单的订阅...
_eventAggregator.GetEvent<AfterLineAmountPaidEvent>().Subscribe(OnLineAmountPaidChanged);
OnLineAmountPaidChanged 方法永远不会受到影响。
在代码隐藏中,我正在发布事件......
_eventAggregator.GetEvent<AfterLineAmountPaidEvent>().Publish(
new AfterLineAmountPaidEventArgs
{
InvoiceLinesSelectedAmount = InvoiceLinesDataGrid.ItemsSource
});
我想知道它是否与 Prism 库和事件聚合器的实例化有关。在VM中,我通过构造函数创建它......
IEventAggregator eventAggregator
我正在使用基本 VM 扩展 VM...
: base(eventAggregator, messageDialogService)
然后,我将实例化分配给我使用的私有,如前面的代码所示......
private readonly IEventAggregator _eventAggregator;
在代码隐藏中,我按如下方式实例化事件聚合器......
private readonly IEventAggregator _eventAggregator = new EventAggregator();
当我使用断点单步执行代码时,我注意到一旦代码从 2(二)到 0(零)命中代码隐藏,订阅就会发生变化。这就是为什么我认为它正在以我使用库的方式在后面的代码中为应用程序重新实例化。
是否有不同/更好的方式来完成这种沟通?我是否错误地实例化了事件聚合器?
任何建议都是有帮助的。
解决方案
你的猜测是正确的。问题是你有两个EventAggregator
对象。您的代码不应该实例化 EventAggregator。它应该是从 Prism 给你的。您的代码隐藏需要获得与EventAggregator
您的视图模型相同的实例。
好处是您可以将相同的内容注入EventAggregator
到与您的视图模型一起使用的视图中,就像视图模型获取它一样。通过构造函数注入。然后从那里将它传递给任何其他代码隐藏者。
这是一个例子。我有一个名为 my 的 Prism 模块ExploreModule
。在模块派生类中,我的 RegisterTypes 函数如下所示:
public void RegisterTypes(IContainerRegistry reg)
{
reg.RegisterForNavigation<ExploreView>(ModuleKey.Explore);
}
在我的应用程序中,与我一起使用的视图模型ExploreView
称为ExploreVm
. 您看不到它在此处列出,因为我使用 Prism 的“视图模型定位器”方法。但基本上每当 Prism 创建 my 时ExploreView
,它都会创建一个ExploreVm
与之配套的。
这意味着我可以将任何我想要的注册服务添加到ExploreVm
or的构造函数中ExploreView
。包含IEventAggregator
所以我编辑我ExploreVm
的IEventAggregator
. 这是我使用的那个。它还添加IEventAggregator
了我个人创建和注册的另一项服务。由于 Prism 为我创建了这个视图模型,所以它只为我提供了两种服务。
public ExploreVm(ICaptureService capSvc, IEventAggregator agg)
{
// ...
}
ExploreView
如果我愿意,我也可以用同样的方式编辑
public ExploreView(IEventAggregator aggregator)
{
Aggregator = aggregator;
InitializeComponent();
}
您应该有一个类似的视图/视图模型对,您可以在其中执行相同的操作。
现在,如果我有一些需要访问的子视图/控件(不是由 Prism 创建的)IEventAggregator
,那么我将IEventAggregator
在属性中公开它或使用其他方式将其传递下去。但是这个 Prism 创建的视图/视图模型是入口点。
无论如何,关键是您不要创建 EventAggregator。棱镜可以。
推荐阅读
- apache-kafka - 使用 confluent-kafka-python 来自融合云代理的 ProduceResponse
- video - 如何在不丢失音频同步的情况下将多个视频与 AVMutableComposition 组合?
- flutter - Flutter - 添加流时无法添加事件
- javascript - 如何解决 Chrome 中的“一个不同的源子框架试图创建一个 JavaScript 对话框”警告?
- blazor-server-side - 多域 Blazor Web 应用程序
- javascript - 部分更新大对象的事件
- spring-boot - SpringBoot单元测试控制器mvc总是返回404
- python - settings.py 文件中的 Celery 配置
- spring - 即使在先前经过身份验证和授权成功之后,java spring + login 端点也不会被调用
- tensorflow - 如何设置多卡训练以及如何在tensorflow检测API中指定GPU训练