After quite a long time i've finally found some time to continue writing the tutorial serie. This time i'm going to keep updating this thread in the next few days in order to complete the part #5 so keep checking it if you're interested.
This time i'm going to show several topics that will help you to share information between views and viewmodels and those are:
- ViewModel Manager
- Converters
- Binding behaviour
- PropertyChanged listener
- Global exception handling(bonus

)
The ViewModel Manager:
Since i started to write this tutorials you have probably come across the ViewModelManager class and the IManagable interface. As of now both of them are included in the projects provided by me but never used. First of all the ViewModelManager class is a basic implementation to share information between your viewmodel classes. A well written application usually doesn't necessary need to share information between viewmodels if the proper logic is used. However by experience i know that isn't the case in a hell bunch of complex applications as there is a time when you just need to share information between viewmodels.
How is that done? quite simple. If you check the ViewModel base class you will quickly spot this code in the constructor:
Code:
var parseable = this as IManageable;
if(parseable != null)
{
parseable.InstanceID = Guid.NewGuid();
ViewModelManager.AddViewModel(this);
}
What we do here is cast the current viewmodel as IManageable. If the current viewmodel implements the IManageable interface it's going to automatically be added to the ViewModelManager list. The interface itself is very basic as well since it should serve as a template for your further implementations. Now if you check the ViewModelManager class you will find out that as mentioned is also a basic implementation of what a manager should be. The class is very straightforward and as you can see it implements a list of viewmodelbase items and offer few methods to get or add viemodels. Remember, the base of each viewmodel is the viewmodelbase
The ViewModelManager class as you can notice is static and i did that on porpuse. Being static means you can access it anytime as long as the namespace is included on your viewmodel. Now that we know what the porpuse of the ViewModelManager class is let's now explain how it works. The manager in order to work properly needs to be implemented correctly and for that you will have to keep this in mind:
In the scenario above we have an application that has several viewmodels. Each viewmodel is unique and represent the main logic of each element(main, item list control, child control, child control of child). Elements provided by controls such as items are obviously viewmodels too but those should not implement the IManageable interface but only the main ones. If you check the ViewModelManager implementation you can see that each element added to the manager must be unique and not of the same type(at least in my basic implementation).
Now let's make the following scenario... the Child control of child viewmodel is called "ChildOfChildViewModel" and the Child control viewmodel is called "ChildViewModel". Let's say i'm currently in the ChildOfChildViewModel class and want to access a property of the ChildViewModel class. There are different ways of doing that but the simple one is done as follows:
Code:
var childVM = ViewModelManager.GetViewModel(typeof(ChildViewModel)) as ChildViewModel;
if(childVM != null)
{
// Voila! we have a reference to the parent viewmodel and can now access it's property.
}
By adding the code above you get access to the ChildViewModel if it implements the IManageable interface. The same can be done from any item viewmodel as well. There are also other ways to accomplish that but this is the simpliest one. I will cover other ways later in this tutorial when i talk about Binding behaviour and PropertyChanged listener.
Converters:
Logic between your code and UI. Basically what they do is provide a pre-determined information at binding time. How do you create one? pretty simple. Start by creating a class that implements the IValueConverter interface like this:
Code:
public class ManagerVMConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Type type = Type.GetType(string.Format("MVVMTutorial.ViewModels.{0}", parameter.ToString()));
return ViewModelManager.GetViewModel(type);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
As you can see the interface contains two methods which are "Convert" and "ConvertBack". This time we are going to focus in the "Convert" method only. The method itself is very straightforward and provide you all the information coming from the UI object that implements it. How do we implement the ManagerVMConverter class in your UI? again, pretty simple:
Start by adding the namespace where the converter is located to your XAML code like for example:
Code:
xmlns:converters="clr-namespace:MVVMTutorial.Converters"
Now add the following to your Window or Control XAML resource like for example:
Code:
<Window.Resources>
<converters:ManagerVMConverter x:Key="ManagerConverter"/>
</Window.Resources>
What we do here is declare a key to use the converter anytime. For example... if you want to add a certain viewmodel that was already registered in the ViewModelManager class you can do it directly on your XAML now without the need of code behind. Let's say you have a simple button and you want to use the "ChildViewModel" as DataContext. Normally you will just go to codebehind and do it but let's do it directly in XAML now:
Code:
<Button DataContext="{Binding Converter={StaticResource ManagerConverter}, ConverterParameter=ChildViewModel}"/>
As you can see here i'm using a button and directly binding the DataContext property to the Converter which use the previously created resource key. By adding the ConverterParameter of "ChildViewModel" i'm providing the type name of the viewmodel registered to use. After that the button is going to use the "ChildViewModel" class automatically. The same can be done on every single element and you can use the same viewmodel on all UI elements of your need without to modify the default viewmodel given to the main control. This step is very important when you want to display information that is stored in a viewmodel other than the one you are currently using on your current view. Since your button DataContext binding has changed you can now bind other properties of the control as usual using the given viewmodel property.
Isn't that cool??? this method saves you from having to get instances of foreign classes or even worst... having to write huge loops and methods just to access a single property. If used properly this method could bring a huge speed up by avoiding unnecessary code. At the end of this tutorial i will provide a project to show what i just explained. For the time being try to figure out yourself using my explanation.
To be continued in the next few days......... enjoy!