简体   繁体   English

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

[英]How to communicate between code-behind file and ViewModel

I am trying to send a message from a code-behind file of a View to a separate ViewModel in order to notify the ViewModel that a collection has changed. 我试图将消息从视图的代码隐藏文件发送到单独的ViewModel,以便通知ViewModel集合已更改。 I understand the code-behind file usage breaks MVVM principles, but I believe it is justified in this situation. 我了解使用代码隐藏文件违反了MVVM原则,但是我认为在这种情况下这样做是合理的。

I have a WindowsForms control that I have to use and thus need a WindowsFormsHost in my application. 我有一个必须使用的WindowsForms控件,因此在我的应用程序中需要一个WindowsFormsHost The WindowsFormsHost sits in the code-behind file, where I'm doing all the groundwork to set up my WindowsForms control (which is a video capture control, by the way). WindowsFormsHost位于代码隐藏文件中,在这里,我正在做所有基础工作来设置WindowsForms控件(顺便说一下,它是一个视频捕获控件)。

A separate View/ViewModel handles the videos and images captured by this control. 单独的View / ViewModel处理此控件捕获的视频和图像。 At the start of the application, the ViewModel asks the Model to retrieve all of the image/video thumbnails, and then places them in a ListBox in the view for the user to see. 在应用程序启动时,ViewModel要求模型检索所有图像/视频缩略图,然后将它们放在视图中的列表框中,以供用户查看。 Here is where I'm lost. 这是我迷路的地方。

I need to communicate to the ViewModel that a new image/video has been captured and that the View should be updated. 我需要通知ViewModel已捕获新的图像/视频,并且应该更新View。 I already have my list of thumbnails set up as an ObservableCollection and have set up the OnPropertyChanged and the NotifyCollectionChanged events. 我已经将缩略图列表设置为ObservableCollection ,并设置了OnPropertyChangedNotifyCollectionChanged事件。

Those should work, if they were being executed. 如果它们被执行了, 那么它们应该起作用。 I noticed that they never are, because there is nothing telling them to do so. 我注意到他们从来没有,因为没有任何事情告诉他们这样做。 I tried to set up an event that would be raised after a file was successfully saved, but since the file-saving takes part in a different class(a callback class required by the capture control), I need to have an instance of that class in my ViewModel to subscribe to the event. 我试图设置一个event ,该event在成功保存文件后会引发,但是由于文件保存参与了另一个类(捕获控件所需的回调类),因此我需要具有该类的实例在我的ViewModel中订阅该事件。

This means I need to create another instance in my ViewModel, which isn't the instance of the class that is doing the file-saving. 这意味着我需要在ViewModel中创建另一个实例,而不是正在执行文件保存的类的实例。 Is there an approach I can take that will allow me to communicate between the code-behind file and image/video ViewModel after a UI button is pressed? 有没有一种方法可以让我在按下UI按钮后在代码隐藏文件和图像/视频ViewModel之间进行通信?

Essentially, my desired order of operations is as such: 本质上,我想要的操作顺序如下:

1.) User opens application and sees video stream in one pane and already captured image/videos thumbnails in another (these are stored in two separate folders inside the solution directory for now) 1.)用户打开应用程序,在一个窗格中查看视频流,在另一个窗格中查看已捕获的图像/视频缩略图(目前,它们已存储在解决方案目录中的两个单独的文件夹中)

2.) User clicks on either "Capture Video" or "Still Image" button, which will either begin video capture or take an image of the current video frame. 2.)用户单击“捕获视频”或“静态图像”按钮,这将开始视频捕获或获取当前视频帧的图像。

3.) If video capture was clicked, user will have to click "Stop" to stop video capture. 3.)如果单击了视频捕获,则用户必须单击“停止”以停止视频捕获。 The video will be saved in the video folder. 视频将保存在视频文件夹中。

4.) If "Still Image" was clicked, a frame is captured and stored in an "images" folder. 4.)如果单击“静态图像”,则会捕获一帧并将其存储在“图像”文件夹中。 I am creating a BitmapImage of the frame after it is captured. 捕获帧后,我正在创建该帧的BitmapImage

5.) The ImageViewModel should be notified that there has been a new image/video saved, and should update the captured images/videos pane. 5.)应该通知ImageViewModel已经保存了新的图像/视频,并且应该更新捕获的图像/视频窗格。

This sounds to me like the perfect situation for an event, but I can't think of how to properly wire it up without creating extra instances of classes. 在我看来,这听起来像是某个事件的理想情况,但是我无法想到如何在不创建额外类实例的情况下正确地将其连接起来。 If some code examples would help, please let me know. 如果某些代码示例有帮助,请告诉我。

You could the event aggregator pattern. 您可以使用事件聚合器模式。 There are implementations of this included in MVVM frameworks such as Prism and Caliburn.Micro. MVVM框架(例如Prism和Caliburn.Micro)中包含此功能的实现。 Caliburn.Micro includes a NuGet package which just includes the event aggregator, so you don't need to pull down the full framework. Caliburn.Micro包含一个NuGet程序包,其中仅包含事件聚合器,因此您无需删除完整的框架。

Have a look here - http://nuget.org/packages/Caliburn.Micro.EventAggregator and here for documentation. 在此处查看-http://nuget.org/packages/Caliburn.Micro.EventAggregator,在此处获取文档。

In your case the publish of the event can happen in the code behind, and the subscriber would be your view model which responds to the event. 在您的情况下,事件的发布可以在后面的代码中进行,而订阅者将是您对事件进行响应的视图模型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM