I am using the MVVM pattern in my WPF application. In one of my Views I have a button that when clicked uses Commands to talk to its ViewModel. The problem I have is that I need the ViewModel to then talk to other ViewModels to call some of their public methods. I use IOC (Unity) and inject the container into the first ViewModel, so could access the others by using this. I’m not sure if this fits in with the MVVM concept.
Is it possible for all my ViewModels to somehow subscribe to the one button click?
Are any of these the recommended way of solving this problem or is there a better way?
To explain a bit more about my application, each view is a tab control with several textboxes. On the first tab there is also a button and combobox. The user is free to enter their own data or select an option from the combo. In this instance, if the button is then clicked I need all the tabs to load their textboxes based on the selected item in the combo from the first tab. I somehow need to wire this button click in such a way that the value from the combo is passed to all the related viewmodels.
You can use the EventAggregator. Have the command publish an event that the other ViewModels can subscribe to.
When the event is raised they'll all get the event, without needing for one VM to know the other VMs
Another option is to use Composite Commands instead of a regular command.
Make the command the button uses a composite command, and have the other viewmodels register to that Composite command.
You could go a few ways with this one:
use some kind of eventing framework to notify all subscribers if something happens: eg Prism EventAggregator. For this to work you'll need to set up Prism obviously. There are other (MVVM) frameworks out there which support some kind of event/message system like Caliburn.Micro or MVVMLight
Create a MasterViewModel that contains all the child viewmodels for all the tabs. This way the 'master' can subscribe to the PropertyChanged events from its children and execute the appropriate actions. Or the Master can even contain the commands which you are binding to.
I would recommend using some form of "Messenger" service. By this, I mean a class that implements the "Subscription Pattern."
I'm not sure which MVVM library you might be using, but if you look at the "MVVM Light Toolkit" - which is available on CodePlex - you will find a very light implementation of a Messenger there.
Basically each ViewModel will subscribe to receive a specific notification and your ViewModel with the combo box and button will publish the message when the button is clicked. It is really quite flexible in how you send the messages and your ViewModels don't need to know anything about each other.
If you are using the MVVM lite toolkit from GalaSoft you have access to the Messenger which would allow you to send a message that you can subscribe to in each of your view models.
// Send message from command handler
Messenger.Default.Send<MyMessage>(new MyMessage());
// Register for message in view models.
Messenger.Default.Register<MyMessage>(this, MyMessageReceived);
// Method to do work
private void MyMessageReceived(MyMessage myMessage)
{
// Do Work
}
Related
Can anyone please explain difference between Triggers, Behaviors and Commands. I tried to search on this, but could not find anything useful.
And would also like to know in which scenario which one should be preferred and which one is used frequently among them?
Behavior is a way of interactivity without writing code. Behaviors makes interactivity much simpler for the designers. In short, a behavior is a reusable piece that encapsulates some functionality that can be attached to an object to extend its built-in interactivity capabilities.
Commands are used to encapsulate a piece of logic, which various Silverlight controls can bind to and execute in response to an event, such as a button being clicked. You can expose a command from a ViewModel as a property and bind the Command property of a control in the View to it. When the control is clicked, the command will be executed.
In MVVM scenarios, triggers are used to notifying the view of an event from a ViewModel.
For example, perhaps the view needs to navigate to another view once a save operation is
complete. You can implement this behavior by raising an event from the ViewModel that the view can listen for by doing either of the following:
• Wiring up an event handler in the view’s code-behind and writing some code to
respond to the event (Not recommended approach)
• Implementing a trigger in the view that listens for the event and responds accordingly
You can see this, this and this for more explanations.
Also, Pro Business Applications with Silverlight 5 is a very good reference for you.
We're doing a WPF application using Prism.
We're using the 'view-first' approach where our views are injected with the VM (IFooViewModel).
We want to hook up a UI action in a view to display a modal dialog box. We want to do this the 'proper' Prism way, i.e. just specifying a URI and not hard-coding a particular View or ViewModel.
There seems to be very few examples of achieving this seemingly trivial goal.
As I assume you are also using the DI containers from PRISM, you can try using Inversion of Control. Basicly what you do is the following.
Each view has it's own interface. In that interface you define your code with events and such. You then inject the Interface into the viewmodel without it ever knowing anything about the view. Except the necessary events of course
Sometimes a Domain Model object with a business logic (DDD) when calling a method an event is fired.
In my situation, a viewmodel (for a given view) encapsulates the domain object and needs to register and react on those domain events (i must use events because that same domain object can be managed by many loosely coupled views along with their viewmodels).
I also need to unregister to those events when that particular context is hidden.
I can handle this register/unregister/dispose in parallel with show/hide/dispose of that view using databinding, programmatically or whatever if the scenario keeps simple enough...
The problem comes when visualization logic comes with DataTemplates.
How can I know when that datatemplate becomes hidden so that I can unregister my events? is it there a better way with wpf to handle this, instead of adding more events?
What is the best practice to handle this scenario in a good MVVM approach?
edit: ok, the problem is structural. sometimes choices made inside the project has forced us to work in an atypical manner... in a good mvvm approach this problem should not happen
I'd be careful in making the ViewModel dependent on the View for making things right.
So what I would do is provide a property (Show? Visible? Open?) on the ViewModel that has a TwoWay binding with the View so the ViewModel can monitor the property.
I have what, on the face of it, seems to be a really simple requirement - to be able to show a messagebox from within the view model of my WPF prism application.
Reading the documentation everything sounds good when I'm reading about Interaction Requests but I then find out that WPF doesn't support PopupChildWindowAction.
How are people getting around this. Basically I want a Messagebox in my shell module / or a infrastructure module that will subscribe to events and popup when that event is published.
Another issue I had was I want the popup to be centered on the parent window (the shell).
Just wondered how other people approached this. There seem to be a number of different ways to go but neither seem to fit the bill exactly.
From A CodePlex post by Karl Shifflet:
I've written a WPF version of the Interaction Request for my the Box MVVM Training here:
http://visualstudiogallery.msdn.microsoft.com/en-us/3ab5f02f-0c54-453c-b437-8e8d57eb9942
Install this Visual Studio Extension.
Create a new project with the MVVM Training Template.
Check out DialogInteractionRequestView.xaml and its implementation.
Cheers,
Karl
Use the RegionPopupBehavior from Prism 2.2 RI.
Use the EventAggregator in PRISM to subscribe to events, and have an in-memory presenter that listens for an event and then creates a view using the event data and calls ShowDialog on the view.
The dialog result can then be used to publish a 'response' event that would be routed back to the process that initiated the event that resulted in the display of the dialog.
Since PopupChildWindowAction is only in Silverlight, I have created my own PopupAction by inheriting from TriggerAction class and simply overridden body of Invoke() method to bring up a PopupWindow where I can pass any UserControl from xaml within the prism interaction trigger tag. From within ViewModel I am raising interactivity request event which triggers my PopupAction in view and opens the popup with desired user control being displayed onto it. Seems to work. I'll need to polish the example more. But here is a link -
http://wpfgrid.blogspot.com/2013/01/simple-prism-mvvm-way-to-display-dialog.html#step3
My client is trying to hook to a usercontrols Loaded Event in the View Model. Basically they want to know when the controls loaded event triggers inside the view model. They are looking for a way to do it without code behind the xaml. Is this even feasible. I am looking into whether I can route the loaded event to the viewmodel in the xaml.
One way of doing it is to use InvokeDataCommand. You'd specify the trigger's EventName as Loaded, and then your command (defined in your VM) would execute when Loaded event is fired.
You need to look into commanding. Silverlight support is fairly weak compared to WPF but it does contain the ICommand interface. You can extend controls to give them command properties or implement them via an attached property. The commands basically invoke themselves once an action has occurred in the UI. They are totally independent of how the UI is built (or at least they should be) and so can be completely unit tested.