如何在代码隐藏文件和ViewModel之间进行通信

本文关键字:之间 通信 ViewModel 代码 隐藏文件 | 更新日期: 2023-09-27 18:26:05

我正试图从视图的代码隐藏文件向单独的ViewModel发送消息,以便通知ViewModel集合已更改。我知道文件使用背后的代码破坏了MVVM原则,但我相信在这种情况下它是合理的。

我有一个必须使用的WindowsForms控件,因此在我的应用程序中需要一个WindowsFormsHostWindowsFormsHost位于代码隐藏文件中,我正在那里做所有的基础工作来设置我的WindowsForms控件(顺便说一句,这是一个视频捕获控件)。

单独的View/ViewModel处理此控件捕获的视频和图像。在应用程序启动时,ViewModel会要求Model检索所有图像/视频缩略图,然后将它们放在视图中的ListBox中供用户查看。这就是我迷路的地方。

我需要向ViewModel传达已经捕获了新的图像/视频,并且应该更新View。我已经将缩略图列表设置为ObservableCollection,并设置了OnPropertyChangedNotifyCollectionChanged事件。

这些应该有效,如果它们正在被执行。我注意到它们从来都不是,因为没有任何东西告诉它们这样做。我试图设置一个event,它将在文件成功保存后引发,但由于文件保存是在另一个类(捕获控件所需的回调类)中进行的,我需要在ViewModel中拥有该类的实例才能订阅该事件。

这意味着我需要在ViewModel中创建另一个实例,它不是正在保存文件的类的实例。有没有一种方法可以让我在按下UI按钮后在代码隐藏文件和图像/视频ViewModel之间进行通信?

本质上,我想要的操作顺序是这样的:

1.)用户打开应用程序,在一个窗格中看到视频流,在另一个窗格上看到已捕获的图像/视频缩略图(目前这些缩略图存储在解决方案目录中的两个独立文件夹中)

2.)用户单击"捕获视频"或"静止图像"按钮,将开始视频捕获或拍摄当前视频帧的图像。

3.)如果单击了视频捕获,用户必须单击"停止"才能停止视频捕获。视频将保存在视频文件夹中。

4.)如果单击"静止图像",则会捕获一帧并将其存储在"图像"文件夹中。我正在创建一个BitmapImage的帧后,它被捕获。

5.)应通知ImageViewModel已保存新的图像/视频,并应更新捕获的图像/图像窗格。

在我看来,这是一个事件的完美情况,但我想不出如何在不创建额外的类实例的情况下正确地连接它。如果一些代码示例会有所帮助,请告诉我。

如何在代码隐藏文件和ViewModel之间进行通信

您可以使用事件聚合器模式。MVVM框架(如Prism和Caliburn.Micro.Caliburn.Micro)中包含了这方面的实现。Micro包括一个NuGet包,其中只包括事件聚合器,因此您不需要拆除整个框架。

看看这里-http://nuget.org/packages/Caliburn.Micro.EventAggregator以及此处的文档。

在您的情况下,事件的发布可以在代码后面进行,订阅者将是响应事件的视图模型。