简体   繁体   中英

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. I understand the code-behind file usage breaks MVVM principles, but I believe it is justified in this situation.

I have a WindowsForms control that I have to use and thus need a WindowsFormsHost in my application. 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).

A separate View/ViewModel handles the videos and images captured by this control. 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. 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. I already have my list of thumbnails set up as an ObservableCollection and have set up the OnPropertyChanged and the NotifyCollectionChanged events.

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.

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. 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?

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)

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.

3.) If video capture was clicked, user will have to click "Stop" to stop video capture. 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. I am creating a BitmapImage of the frame after it is captured.

5.) The ImageViewModel should be notified that there has been a new image/video saved, and should update the captured images/videos pane.

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. Caliburn.Micro includes a NuGet package which just includes the event aggregator, so you don't need to pull down the full framework.

Have a look here - http://nuget.org/packages/Caliburn.Micro.EventAggregator and here for documentation.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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