Introduction
Building M-V-VM based applications comes in very handy. This article comes to introduce a generic approach for View Model's decoupling.
Background
Building UI Applications using WPF, M-V-VM comes as a great mechanism for decoupling the data from its presentation. Every piece of UI, being a Window, Page or User Control, gets its own view model. Most applications have a hierarchical structure which corresponds with the Views structure. Thus, a Page holding a User Control would have its view model keep the User Control's View Model as a class member. My problem begins when I want a certain action in a control to carry implications on other sections of the applications. I used to solve this by having a "Parent
" property in the descendent View Model. This worked out fine until I got to a part in which I wanted to reuse the control in a new part of the application. Then I understood that using this method restricts my ability for code reusability. I noticed that decoupling should be done in the View Model itself and not only between the View and the View Model. That is when I came up with the "IViewModel
" solution.
I've started thinking of the different View Models as independent units, and as such that must not hold any knowledge about their initiators. My solution for this was creating the IViewModel
interface. Using this interface enables the View Model do two things:
- Notify View Models on events which occurred on other View Model's View.
- Consume services from other sections of the application.
Notifying on events is pretty understandable, however the second section is a bit more confusing. Applications usually don’t stand on their own but hold connection to outer scopes, being a DB or perhaps remote services. I prefer holding a single point to these services.
IVIewModel
The IViewModel
is a simple interface:
public interface IViewModel
{
IViewModel VMParent
{
get;
}
void HandleEvent(IViewModel sender, object param,
ViewModelOperationsEnum viewModelEvent);
}
Every ViewModel
class in the application implements this interface. In case a View model is only a pipe between its children and its parents, the handle event implementation is usually as follows:
public void HandleEvent(IViewModel sender,
object param, ViewModelOperationsEnum viewModelEvent)
{
if (VMParent != null)
{
VMParent.HandleEvent(sender, param, viewModelEvent);
}
}
Using the Application
The application consists of four projects, two on the client side and two on the server side. Upon applications run, two windows would appear, a GUI window which contains a TreeView
object and a console window. Place the two windows next to each other. Open the tree view node and parse through the nodes. You'll notice that each node carries a request to the server. This is done without having the node hold any knowledge of the server.
History
- May 29 2009: Initial release