Iam using MVVM and have a main window with Close button and it is bound to the MainWindowViewModel's ICommand command.
In the main window there are two UserControl1 and UserControl2 which is bound to viewmodels UserControlVM1 and UserControlVM2 respectively.
UserControlVM1 and UserControlVM2 has command named CleanUp that will clean up the resources.
So Whenever the close button is clicked on the mainwindow, i wanted to call the CleanUp command of Usercontrol viewmodels. How can we do this in XAML or any other alternatives?
A common implementation for communication between ViewModels is the Mediator Pattern which describes an object common between your ViewModels providing a Publish/Subscribe model. When an Event of interest occurs in an object it publishes a notification to the Mediator, one or more objects that are subscribed to that particular Event of the Mediator are then notified of the Event occurring in the original object.
Mediator Pattern Example
You should consider a view model first approach, in which case the MainWindowViewModel would have references to the UserControlVM1 and UserControlVM2, and can call the CleanUp methods directly.
You should consider using an MVVM framework if you're using MVVM.
You could inspire yourself from a technique from Prism's developer guide.
In Patterns and Practices' Prism Framework, CompositeCommand allows several ViewModel to register their own command against a single CompositeCommand, so that all can be called with one single call.
You'd also need this global class that is referenced in all your ViewModels, but not necessarily a static one since you don't have loose coupled modules.
Related
I'm a newcommer in Caliburn.
I have a couple of questions of MVVM and Caliburn.
How can a view invoke a method explicitly on a ViewModel? Caliburn invokes a ViewModel constructor first. So if it is, then where the instance is going to be contained? The code inside my View create a new instance at the moment (I need to invoke a method on ViewModel explicitly). But regarding that ViewModel should be instantiated already, this is silly.
How can I force a binding update on the UI thread?
Caliburn.Micro has the concept of actions to invoke verbs on your view models from the view. You can largely use conventions for this, so for example if you have a Button in your view with x:Name="Save", then your Save method on the view model will be invoked when the Button is clicked.
You can always use explicit bindings to override the conventions, as well as providing your own conventions, and Caliburn.Micro also provides attached properties to associate view model methods to events in the view.
In terms of forcing a UI update, your view models will implement INotifyPropertyChanged, and Caliburn.Micro provides base implementations of this, including PropertyChangedBase, and Screen (which adds life cycle).
You can then use the Caliburn.Micro supplied helper method to invoke the PropertyChanged event. This is called NotifyOfPropertyChange, and it can take an expression lambda to specify which property to notify, rather than using a magic string.
I want to change a DependencyProperty of my ViewModel from a class which connects the application to a database.
This class raises events which should initiate a change of some properties in my ViewModel.
How can I realize that? I don't have the Dispatcher of the View.
I'm assuming you don't really have dependency properties on your viewmodels but rather normal C# properties which raises the PropertyChanged event.
If so, you should be fine already. Modify your properties from your background thread (normal concurrency issues apply obviously) and when they are bound to a WPF element's Dependency Property the runtime system will take care of marshalling the change to the proper thread (by using the view's Dispatcher object)
This works for normal properties, I'm not sure it works for ObservableCollections.
There are also different approaches for doing the marshalling inside the viewmodels. The simplest way is to just store the value of Dispatcher.CurrentDispatcher in your viewmodel's constructor. This works as long as your viewmodels are created on the UI thread.
One immediate solution to the problem is to capture the view's Dispatcher and store it on the view model when you create it, so you can Invoke/BeginInvoke the change to it in response to the event.
That being said, you should consider making your viewmodels use INotifyPropertyChanged with CLR properties rather than DependencyProperties to avoid issues like this. That way, any thread can make changes to your viewmodel and have the results reflected in the view.
I'm very new to MVVM and even WPF to some degree so bear with me...
I've got a MVVM application that has a main window, containing a viewmodel instance of different types depending on application state. One of these viewmodels is an options screen which contains a button to restart the application and log into the database as a different user. Using RelayCommand, how can I have the parent, (the main window) handle this command and issue a Window.Close() method call?
Define the RelayCommand on the parent view model. The Associated handlers will also be defined in the parent view model.
Now, when you creat the child view module pass the Paremtn View model object in to the Child ViewModel in the constructor (Dependency Injection Pattern).
Now you can set up the command binding for your view or view model.
Te other alternative would be to actually use a routed command instead of the relay command and let it bubble up to you parentview model.
Let's have a button Command property bound to a custom command.
When should I implement ICommand and when derive from RoutedCommand? I see that RoutedCommand implements ICommand.
In which case could I need to implement an ICommand?
What about MVVM model? Which one suits better for this purpose?
As you have noticed the RoutedCommand class is an implementation of the ICommand interface, its main distinction if that its function is similar to that of a RoutedEvent:
The Execute and CanExecute methods on a RoutedCommand do not contain the application logic for the command as is the case with a typical ICommand, but rather, these methods raise events that traverse the element tree looking for an object with a CommandBinding. The event handlers attached to the CommandBinding contain the command logic.
The Execute method raises the PreviewExecuted and Executed events. The CanExecute method raises the PreviewCanExecute and CanExecute events.
In a case when you don't want the behavior of the RoutedCommand you'll be looking at your own implementation of ICommand. As for the MVVM pattern I can't say that one solution, it seems that everyone has their own methodology. However, here are a few approaches to this problem that I've come across:
Using RoutedCommands with a ViewModel in WPF
Relaying Command Logic
Simple Command (almost identical to Relay Command but worth reading)
The only thing I would add to Rich McGuire's answer is that RoutedCommands (and their more prevalent descendant RoutedUICommand have to be wired up with event handlers to work correctly.
Most MVVM implementations I have come across attempt to leverage binding against the ViewModel and thus the ViewModel (and not the View) owns the CanExecute/Execute logic.
In contrast, the event handlers move that burden to the View. The handling can then be propagated to the ViewModel, but this means a slightly higher degree of coupling between ViewModel and View (casting + method call, etc.).
I've decoupled events in this WPF application in the following way.
What is the best way to continue decoupling?
Shell.xaml:
<Button x:Name="btnProcess"
Content="Process"
Margin="10"/>
Bootstrapper.cs:
public void Run()
{
Shell shell = new Shell(new Customer());
shell.Show();
}
Shell.xaml.cs:
public Shell(IPerson person)
{
InitializeComponent();
btnProcess.Click +=new RoutedEventHandler(person.Process);
}
Customer.cs:
public class Customer : IPerson
{
public void Process(object sender, RoutedEventArgs e)
{
Button theButton = (Button)sender;
theButton.Content = "Customer processed.";
}
}
The above code successfully decouples the view Shell from the model Customer:IPerson so that I can swap in e.g. a model Employee:IPerson etc. which handles "Processed" in its own way. That was the first goal.
But now:
how do I decouple the Processed method from talking specifically to a Button, so that it could also talk to a MenuItem or a ListView which fires the event in the view and so that it doesn't even have to be an element at all that calls it, e.g. a unit test class?
how do I alter other elements of the view other than the sender (Button), e.g. how would I alter the status bar in Shell? I see two ways:
I could either build a container which holds all views and inject the container in the Customer upon creation, then the customer can look in the container and manipulate the calling view anyway it wants (although I would have to somehow match the view that sent the event and the view in the container as the same one)
I could somehow send the whole view (Window object) to the Model with the eventargs when firing the event, although the Model would need some way of knowing (via interface) what kinds of regions were available to manipulate at runtime
How would you continue this application in the direction of a more decoupled design?
What pattern is this actually, e.g. MVC, MVP, MVVM? I only see a view (Shell) and a Model (Customer).
How would a Presenter fit in?
How would a ViewModel fit in?
How would a Controller fit in?
I suggest you to implement your event handling using commands instead of classic events.
Its very easy in WPF because the command pattern is already implemented, and you can tell all of your UI inputs (button, menu item...) that their command is [name of your command] and handle all of them in one place.
Cameron MacFarland did a good job here, but I can add a little.
When following M-V-VM, the tools in your box for decoupling are data binding, commands, attached behaviors and interfaces. Data binding should be self evident. You've already gotten a good description of commands, but I'd suggest you avoid RoutedCommand and stick with an ICommand implementation. Attached behaviors are attached DependencyProperty's that subscribe to events on the element they are attached to, and in this scenario would be used to relay event handling to the ViewModel. Interfaces give you the greatest flexibility, but you have to work out how to pass the interface to the ViewModel. The best way to learn all of this right now is to Google and to look at existing M-V-VM frameworks. Here's a list of frameworks:
Prism/Composite WPF (http://www.codeplex.com/CompositeWPF). This one comes from the Microsoft Patterns & Practices group. Lots of good stuff here, but one of the examples of the three things above that you can learn from here is how to use ICommand. Prism includes a DelegateCommand that implements ICommand and simplifies using commands from a ViewModel in M-V-VM.
Caliburn (http://www.codeplex.com/caliburn). Recently released, one of the key things you can learn from this one is how to use attached behaviors, which this library uses for it's "Actions".
Onyx (http://www.codeplex.com/wpfonyx). Disclaimer: I'm the author of this one. This one hasn't been released yet, though the current alpha source is available. This one provides a novel solution to the problem of how to provide interfaces to your ViewModel.
As Chen suggests, i'd look into the Command pattern: Routed commands
A working example from which i learned a lot can be found on Jaime Rodriquez his blog: Southridge
how do I decouple the Processed method from talking specifically to a Button
Commands. Put a command in the IPerson interface and call that command from the Shell's xaml.
how do I alter other elements of the view
Properties and Binding. If you have a property showing the state (processed/not processed) then you can use binding to display that property directly in the xaml.
How would you continue
I'd head more down the MVVM path by creating a ViewModel between the Shell and the IPerson. The ViewModel is designed to have 1) The properties needed for bindings, and 2) any Commands that need executing. The ViewModel is designed to provide the UI with what it needs from the Model.
What pattern is this
Currently? Nothing. I see only two objects, the View and the Model. You don't have a Presenter, Controller or ViewModel.
For WPF I prefer ViewModel. See this question for more info on MVVM.