Reputation: 1233
I am developing a simple video player application using Prism 6. I am more familiar with the MVC approach and have a question regarding cross-view communication. Here is how my application is currently designed:
Views:
Each of these views has an associated ViewModel with no functionality as of now.
Model:
My first task is to load a video. Within MenuView
I am able to use OpenFileDialog
to browse for a file. My goal is to somehow communicate with the other view models when a file has been loaded so they can perform the necessary actions (show the first frame, update the length of the video, etc.).
My first thought is to define a service which has a reference to the VideoFile
:
public interface IVideoService {
VideoFile PlayingVideoFile { get; set; }
}
public class VideoService : BindableBase, IVideoService {
private VideoFile _playingVideoFile;
public VideoFile PlayingVideoFile {
get => _playingVideoFile;
set => SetProperty(ref _playingVideoFile, value);
}
}
I am just confusing myself. I am not sure how to implement this communication between the views. How can I implement communication of the model between all of the views in a way that agrees with Prism and MVVM principles?
Upvotes: 0
Views: 244
Reputation: 31
How can I implement communication between all of the View[Model]s in a way that agrees with Prism and MVVM principles?
I assume you are asking about communication between your ViewModels (there generally isn't a reason to have communication between your Views, hence the revision to your question).
There are two ways that I know of that leverage PRISM's codebase for ViewModel-ViewModel communication:
1) The EventAggregator
The EventAggregator
uses a publisher-subscriber model for passing messages between ViewModels. While it can be used for communication with non-ViewModel components, it is generally advisable to limit its usage to just ViewModels.
2) CompositeCommand
s
CompositeCommand
s work by providing globally accessible "registration" points for commands in different ViewModels. Assuming the CompositeCommand
has been initialized (typically in some static constructor), you can simply register your ViewModel Commands with a given CompositeCommand
. This will cause it to be executed every time the CompositeCommand is executed.
For the sake of brevity here, please refer to the existing documentation on both of these techniques for more information. They can be found at the site R. Richards alluded to in his comment (link: http://prismlibrary.readthedocs.io/en/latest/WPF/09-Communication/)
Since you're trying to communicate with your other ViewModels when a new VideoFile
is created/selected through MenuView
, I would recommend the following:
1) Create a CompositeCommand
called ProcessNewVideoFileSelectionCommand (or something to that effect).
2) Register any ViewModel-specific commands that need to respond to a new VideoFile
with ProcessNewVideoFileSelectionCommand (e.g. InfoView's ViewModel will need to change its information to reflect the new VideoFile
)
3) When a new VideoFile
is selected in MenuView, execute ProcessNewVideoFileSelectionCommand. This will cause all Command
s registered with it to execute (assuming that they can execute given the values returned by each of their respective CanExecute(...)
methods).
Upvotes: 1