Introduction

Last time I simply introduced the Cinch framework, and this time, we would do a walkthrough of Cinch and its internals. This is going to be a large article, so it has actually been split over two articles. In this article, I will be covering the following:

Allows view to communicate LifeCycle events to a ViewModel without any hard reference links being maintained, and no IView interface requirements. There is no link at all between the View and the ViewModel.

Has several attached behaviours for common tasks such as:

Numeric text entry

Run an ICommand in a ViewModel based on a RoutedEvent from a XAML FrameworkElement

Have a group of such ICommand/RoutedEvent Events for a single XAML FrameworkElement

Allows the ViewModel to determine if a Model's data should be editable; the UI simply updates via bindings, based on the ViewModel driven editability state. This is available at individual Model field level, so it's very flexible.

Delegate validation rules which allow validation rules to be as granular as necessary.

So I guess the only way to do this is to just start, so let's get going, shall we? But before we do that, I just need to repeat the special thanks section, with one addition, Paul Stovell who I forgot to include last time.

Prerequisites

The demo app makes use of:

VS2008 SP1

.NET 3.5 SP1

SQL Server (see the README.txt in the MVVM.DataAccess project to learn what you have to setup for the demo app database)

Special Thanks

Before I start, I would specifically like to say a massive thanks to the following people, without whom this article and the subsequent series of articles would never have been possible. Basically, what I have done with Cinch is studied most of these guys, seen what's hot, what's not, and come up with Cinch, which I hope addresses some new ground not covered in other frameworks.

Mark Smith (Julmar Technology), for his excellent MVVM Helper Library, which has helped me enormously. Mark, I know, I asked your permission to use some of your code, which you most kindly gave, but I just wanted to say a massive thanks for your cool ideas, some of which I genuinely had not thought of. I take my hat off to you mate.

Bill Kempf, for just being Bill and being a crazy wizard like programmer, who also has a great MVVM framework called Onyx, which I wrote an article about some time ago. Bill always has the answers to tough questions, cheers Bill.

All of the WPF Disciples, for being the best online group to belong to, IMHO.

Thanks guys/girl, you know who you are.

Cinch Internals I

This section will start the dive into the internals of Cinch. As I say, there is far too much for one article, so I am splitting the internals of Cinch over two articles. Hopefully there will be something of use to you here. Well, I hope so anyway.

View Lifecycle Events

When developing with the MVVM pattern, the holy grail is for there to be no coupling at all between the View and the ViewModel. This clean separation between the View and ViewModel is achieved in Cinch, there is no link between them at all, which is ace. However, occasionally it is advantageous for the ViewModel to know something about certain View events, such as:

Loaded

Activated

Deactivated

Close

But we just said that there was no referencing between View/ViewModel and we would like to know about these View events in the ViewModel, so how do we achieve that? The answer lies in Attached Behaviours. What we do is we have a ICommand based property in the ViewModel and we use an attached View lifecycle behaviour and attach the correct View event to the correct ViewModel ICommand. So when the View event is raised, it will actually call a ICommand implementation in the ViewModel.

Cinch provides for this using two things:

A Cinch ViewModel base class called ViewModelBase, which already contains all the View lifecycle ICommand implementation you will need, which, I should point out, can be overridden in the inheritors of the Cinch ViewModelBase class

Some View lifecycle attached behaviours

Let us examine one View lifecycle event, Activated, to see how it works; the others are the same.

Starting with the ViewModelBase classm we can see from the code below (extra code removed for clarity) that there is an ICommand called Activated where the trimmed Cinch ViewModelBase looks like below.

Cinch also provides public bindable (INPC) properties for each of the View lifecycle events (be careful, UserControl does not have Activated/Deactivated, these are only available on Window. These properties are set in the Cinch ViewModelBase, so overriders be aware, if you fail to call the Cinch ViewModelBase in your overrides of the lifecycle methods, these properties will not work. Anyway, here is a full example for the Activated command, the rest work the same.

The eagle eyed amongst you may notice that there is a property called ActivatedCommand within the code above, which actually returns a SimpleCommand and not a ICommand that you may have been expecting and maybe even seen in various other posts. This is all cool, don't worry, the XAML parser and binding system are clever enough to know that any class that implements ICommand can be used in place of an ICommand in a binding. The reason to expose the ICommand as a SimpleCommand is that the SimpleCommand has an extra property that can be used from inside Unit tests. Namely, the CommandSucceeded which is set to true on Command execution completion, so can be used in Unit test Assert statements.

Here is the SimpleCommand code:

using System;
using System.Windows.Input;
///<summary>/// This class provides a simple
/// delegate command that implements the ICommand
/// interface
///</summary>namespace Cinch
{
///<summary>/// Implements the ICommand and wraps up all the verbose stuff so that you
/// can just pass 2 delegates 1 for the CanExecute and one for the Execute
///</summary>publicclass SimpleCommand : ICommand
{
#region Public Properties
publicBoolean CommandSucceeded { get; set; }
///<summary>/// Gets or sets the Predicate to execute when the
/// CanExecute of the command gets called
///</summary>public Predicate<object> CanExecuteDelegate { get; set; }
///<summary>/// Gets or sets the action to be called when the
/// Execute method of the command gets called
///</summary>public Action<object> ExecuteDelegate { get; set; }
#endregion
#region ICommand Members
///<summary>/// Checks if the command Execute method can run
///</summary>///<paramname="parameter">/// The command parameter to be passed</param>///<returns>Returns true if the command can execute.
/// By default true is returned so that if the user of SimpleCommand
/// does not specify a CanExecuteCommand delegate the command
/// still executes.</returns>publicbool CanExecute(object parameter)
{
if (CanExecuteDelegate != null)
return CanExecuteDelegate(parameter);
returntrue;// if there is no can execute default to true
}
publicevent EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
///<summary>/// Executes the actual command
///</summary>///<paramname="parameter">/// THe command parameter to be passed</param>publicvoid Execute(object parameter)
{
if (ExecuteDelegate != null)
{
ExecuteDelegate(parameter);
CommandSucceeded = true;
}
}
#endregion
}
}

OK, so we now have a ViewModel that has a SimpleCommand for Activated that will call a protected virtual void OnWindowActivated() method, but how does this ActivatedSimpleCommand get executed? Well, recall I said there was some attached behaviour magic, so let's look at that next.

First, this is how the View would wire up the View Activated attached behavior:

View Deactivated event, where the SimpleCommand in the Cinch ViewModelBase is called DeactivatedCommand, and the virtual method in the Cinch ViewModelBase is called OnWindowDeactivated()

View Closing/Closed event, where the SimpleCommand in the Cinch ViewModelBase is called Closeommand, and the virtual method in the Cinch ViewModelBase is called OnWindowClose()

View Loaded event, where the SimpleCommand in the Cinch ViewModelBase is called LoadedCommand, and the virtual method in the Cinch ViewModelBase is called OnWindowLoaded()

Again, don't forget there is no standard implementation provided by the Cinch ViewModelBase as this functionality should be performed by overriding these methods in a ViewModel which inherits from the Cinch ViewModelBase.

So all you have to do is inherit from the Cinch ViewModelBase, and you can use these View lifecycle events/properties, just remember to call the base methods.

Numeric Textbox Attached Behaviour

One very common requirement when developing LOB applications is to have numeric only data entry on textboxes. Whilst this is possible to achieve using Regular Expressions and some code-behind and possibly a ValidationRule, wouldn't it just be easier to not let the textbox accept anything apart from numbers in the first place? To this end, Cinch contains a NumericTextBoxBehavior attached behaviour which looks like below. You should also note that this behaviour caters for pasted text using the DataObject pasting event.

With this attached behaviour enabled, only numeric data entry will be allowed for the textbox that has the NumericTextBoxBehavior attached behaviour applied.

Attached Command Behaviour

Continuing with the attached behaviors, it is also sometimes very convenient to be able to fire a ViewModel ICommand from a FrameworkElement RoutedEvent. This is something that the WPF framework does not do out of the box, though Blend 3 does allow this by the use of the Blend Interactivity DLL. If you want an example of that, have a look at my blog post WPF: Blend 3 Interactions / Behaviours.

But we are where we are, and I want people to know how to do this without using a non released DLL from a different product that will more than likely find its way into WPF proper at some stage. So let's continue with how to do it without the Blend Interactivity DLL.

So here is how, Cinch actually provides two alternatives here, attaching a single ICommand to a single FrameworkElement RoutedEvent, or attaching a collection of ICommands to a FrameworkElement using different RoutedEvents.

Let's start simple, and build up from there.

Attaching a single ICommand to a single FrameworkElement RoutedEvent

This is easily done via yet another attached property or two, which you can set on a View FrameworkElement like this:

So we set the RoutedEvent to fire the ICommand and we set the ViewModel ICommand to execute via a Binding.

So all that is left is to look at how this is achieved, which is done with a standard DP or two and a touch of Reflection to get the RoutedEvent from the DependencyObject that declares the RoutedEventName attached DP, and from there, we just create a Delegate which is called when the event is raised, which in turn fires the ICommand that was specified using the TheCommandToRun DP.

This allows a single FrameworkElement RoutedEvent to fire a single ViewModel ICommand and pass down the original EventArgs/Sender and CommandParamtere down to the ViewModel all within the SCommandArgs object. So that means, all you have to do within your ViewModel to use the original EventArgs is something like this:

So you can see that this time, there is an attached property (EventCommander.Mappings) that is expecting a collection of CommandEvent objects. The concept behind this is largely the same, except this time, there is a collection of these CommandEvent objects, but they largely work the same as just described above, so I will concentrate on how the EventCommander.Mappings collection works, and assume the discussion above was enough to explain a single CommandEvent object.

Where it can be seen that behind the scenes, the EventCommander.Mappings collection is populating a CommandEventCollection. The CommandEventCollection inherits from Freezable, as this is a trick you can use to get DataContext inheritance. Basically, what happens is that by inheriting from Freezable, a non-UI element will also get the current UI element's DataContext (which is more than likely the ViewModel). If you did not inherit from Freezable, the CommandEventCollection would not be able to pick up the ViewModels bound ICommand; as it would know nothing about a current DataContext object, it would be null. It's a trick, but it works. If you want to know more, read Mike Hillberg's blog entry: Mike Hillberg's Freezable blog post, and maybe have a look at Josh Smith's DataContextSpy post, which is also very useful.

Anyway, the CommandEventCollection looks like this, where its main job is to maintain the list of current CommandEvents:

Better INPC, No Magic Strings

When working with WPF, it is very common to have your ViewModel/Model classes implement the System.ComponentModel.INotifyPropertyChanged interface for binding notification of property changes. This is typically implemented like this:

The problem with this approach is that the code has magic strings in it which are easy to get wrong. Have a look at the OnPropertyChanged("PersonName"); code shown above. I had originally been using some static Reflection by using LINQ expression trees to obtain the property name. I was using Bill Kempf's excellent Reflect code. The problem with the static reflection Expression tree thing is that it is slow to create the eventArgs each time. One of the readers of this article actually came up with a better solution where the INPC EventArgs are created once and then re-used. I liked this idea a lot, so have now included it in Cinch. The reader's post is available here if you want some more information about this: CinchII.aspx?msg=3141144#xx3141144xx.

Cinch now uses this approach. Here is how it works. There is a static helper class which looks like this:

ViewModel Modes

One of the things I have always struggled with when working with MVVM and using it to produce LOB apps is View mode. For example, it would be nice to have a View that is read only and then the user clicks edit and then all the fields on the View are editable. Now this could be achieved by having a command in the ViewModel that changes from ReadOnly mode to EditMode say, and all the UIElements on the View could bind to some CurrentMode property on the ViewModel. Sounds do'able, but as we all know, things are never as clean cut as that. In my workplace, we have complicated requirements around data entry and there is no way a single mode can be applied to all data entry fields on a single View. No way, we need very granular data entry rights, down to the individual field level.

So this got me thinking. What we need is an editable state for each data item in a UI Model. I thought about this some more and came up with a generic wrapper class which wraps a single property but also exposes an IsEditable property. Now the ViewModel can access these wrappers as they are public properties, on either UI Model classes, or actually public properties in the ViewModel (I expose a CurrentX object of my ViewModel, but others repeat all the UI Model properties in the ViewModel; me, I have no issues with writing straight from the View to the Model, providing it doesn't get to the database if its InValid), so it can bind its data to the wrapper's data property and can disable data entry based on the wrapper's IsEditable property.

Which can then be used as properties on your UI Model classes (or directly on the ViewModel if you want to), like this (don't worry about the inheriting from Cinch.EditableValidatingObject, we'll get to that soon):

Notice the setter is private, this is due to the fact that these objects are immutable, and are only allowed to be set in the constructor. The IsEditable and the DataValue can be changed whenever you like though. The other thing to note is that the Model/ViewModel actually use some Reflection on construction to obtain an IEnumerable<DataWrapperBase> which is then used as a cache, so setting any of the cached DataWrapper<T> properties from that point on is very quick. This is achieved as follows:

In the constructor, we have something like this:

using System;
using Cinch;
using MVVM.DataAccess;
using System.ComponentModel;
using System.Collections.Generic;
namespace MVVM.Models
{
///<summary>/// Respresents a UI Order Model, which has all the
/// good stuff like Validation/INotifyPropertyChanged/IEditableObject
/// which are all ready to use within the base class.
////// This class also makes use of <seecref="Cinch.DataWrapper">/// Cinch.DataWrapper</see>s. Where the idea is that the ViewModel
/// is able to control the mode for the data, and as such the View
/// simply binds to a instance of a <seecref="Cinch.DataWrapper">/// Cinch.DataWrapper</see> for both its data and its editable state.
/// Where the View can disable a control based on the
///<seecref="Cinch.DataWrapper">Cinch.DataWrapper</see> editable state.
///</summary>publicclass OrderModel : Cinch.EditableValidatingObject
{
#region Data
//Any data item is declared as a Cinch.DataWrapper, to allow the ViewModel//to decide what state the data is in, and the View just renders //the data state accordinglyprivate Cinch.DataWrapper<Int32> orderId;
private Cinch.DataWrapper<Int32> customerId;
private Cinch.DataWrapper<Int32> productId;
private Cinch.DataWrapper<Int32> quantity;
private Cinch.DataWrapper<DateTime> deliveryDate;
private IEnumerable<DataWrapperBase> cachedListOfDataWrappers;
#endregion
#region Ctor
public OrderModel()
{
#region Create DataWrappers
OrderId = new DataWrapper<Int32>(this, orderIdChangeArgs);
CustomerId = new DataWrapper<Int32>(this, customerIdChangeArgs);
ProductId = new DataWrapper<Int32>(this, productIdChangeArgs);
Quantity = new DataWrapper<Int32>(this, quantityChangeArgs);
DeliveryDate = new DataWrapper<DateTime>(this, deliveryDateChangeArgs);
//fetch list of all DataWrappers, so they can be used again later without the//need for reflection
cachedListOfDataWrappers =
DataWrapperHelper.GetWrapperProperties<OrderModel>(this);
#endregion
}
#endregion
}
}

And from then on, whenever we deal with the DataWrapper<T> properties, we can use the cached list.

So getting back to how we might use these in our Views, I simply bind to these DataWrapper<T> properties as follows:

So that's all cool, but how do these DataWrapper<T> objects respond to a change in mode state? Well, that is quite simply actually, we do have a Cinch.ViewMode in the ViewModel and whenever that changes state, we need to update the state of all the nested DataWrapper<T> objects in whatever object is we are trying to change the state for (for me, this is always a UI Model, for others this may be the ViewModel itself).

Here is an example AddEditOrderViewModel, which for me holds a single UI Model of type OrderModel. As I say, others will not like this and would have the ViewModel expose all the properties available within a UI Model of type OrderModel. The thing with MVVM is that you do it your own way, and this is my way. I don't care if InValid data gets to the Model just so long as that Model can not be saved to the database.

One thing worth mentioning here is that when the CurrentViewMode property changes, a DataWrapperHelper class is used to set all the cached DataWrapper<T> objects for a particular object into the same state as that just requested. Here is the code that does that:

// The following functions may be used when dealing with model/viewmodel objects// whose entire set of DataWrapper properties are immutable (only have a getter// for the property). They avoid having to do reflection to retrieve the list// of wrapper properties every time a mode change, edit state change///<summary>/// Set all Cinch.DataWrapper properties to have the correct Cinch.DataWrapper.IsEditable
/// to the correct state based on the current ViewMode
///</summary>///<paramname="wrapperProperties">The properties on which to change the mode</param>///<paramname="currentViewMode">The current ViewMode</param>publicstaticvoid SetMode(IEnumerable<DataWrapperBase> wrapperProperties,
ViewMode currentViewMode)
{
bool isEditable = currentViewMode ==
ViewMode.EditMode || currentViewMode == ViewMode.AddMode;
foreach (var wrapperProperty in wrapperProperties)
{
try
{
wrapperProperty.IsEditable = isEditable;
}
catch (Exception)
{
Debug.WriteLine("There was a problem setting the currentViewMode");
}
}
}

Validation Rules/IDataErrorInfo Integration

I recall some time ago Paul Stovell published a great article Delegates and Business Objects which I simply loved, as it seemed to make so much sense to me. To this end, Cinch makes use of Paul's great idea to use delegates to provide validation for business objects.

The idea is simply, the business object has the AddRule(Rule newRule) method which is used to add rules; the business object also implements IDataErrorInfo, which is the preferred WPF validation technique. Then what basically happens is that when the IDataErrorInfo.IsValid property is called against a particular business object, all the validation rules (delegates) are checked and a list of broken rules (as dictated by the delegate rules added to the object) are presented as the IDataErrorInfo.Error string.

However, recall I mentioned a special Cinch class to allow the ViewModel to place a single Model field into edit mode using the Cinch.DataWrapper<T>. Well, we need to do something ever so slightly different for those, we need to do the following:

We need to declare the validation rule like this for Cinch.DataWrapper<T> objects as they are not simply properties but are actual classes, so we need to specify the DataValue property of the individual Cinch.DataWrapper<T> object to validate for the rule.

This also comes into play within the IsValid method you get when you inherit from a Cinch.ValidatingObject object. Let's say you have something like this for a UI Model object:

You would then need to override the IsValid property to look like this, where we come up with a combined IsValid for the entire object based not only on its IsValid but also the IsValid state of any nested Cinch.DataWrapper<T> object, which is very easy as they also inherit from Cinch.EditableValidatingObject which in turn inherits from Cinch.ValidatingObject, so they already have the IDataErrorInfo implementation, so it's not that hard to cope with.

I know this seems a lot of extra work, but the added benefit of the ViewModel being able to set a Model's individual field editability state, and have the View reflect this seamlessly via bindings, simply can not be ignored.

///<summary>/// Override hook which allows us to also put any child
/// EditableValidatingObject objects IsValid state into
/// a combined IsValid state for the whole Model
///</summary>publicoverridebool IsValid
{
get
{
//return base.IsValid and use DataWrapperHelper, if you are//using DataWrappersreturnbase.IsValid &&
DataWrapperHelper.AllValid(cachedListOfDataWrappers);
}
}

Typically, the WPF style we would use for a TextBox that needed to supply validation support for IDataErrorInfo would look something like the following, where we use the Validation.HasError property to change the border color of the TextBox when there is a validation error present.

IEditableObject Support

I have in the past used a pattern called Memento which basically is a cool pattern for support of Undo on business objects. Basically, what it allowed for was the storage of an object's state to a Memento backing object which had the exact same properties as the business object it was storing state for. So when you started an edit on a business object, you store the current state in a Memento and did your edit. If you cancelled the edit, the business object's state would be restored from the Memento. This does work very well, but Microsoft also support this via an interface called IEditableObject which looks like this:

BeginEdit()

CancelEdit()

EndEdit()

So using this interface, we can actually make our business objects store their own state. Now I can take no credit for this next piece of code, it comes from Mark Smith's excellent work. Actually, a fair amount of Cinch is down to Mark Smith's work. Again, I did ask Mark if I could poach his code, he said yes, great cheers Mark.

What Cinch does is provide a base class that can be used to inherit from for your business objects; this base class also supports validation via the IDataErrorInfo interface we just discussed above. Here is how it works. On BeginEdit(), a little bit of Reflection/LINQ is used to store the current object's state in an internal Dictionary. On Canceldit(), the internal Dictionary values are restored to the current object's properties, using the property name as a key into the stored Dictionary state.

So all you have to do to get editability support is inherit your UI model objects from Cinch.EditableValidatingObject. Job done.

Let's see how you might put an object that inherits from Cinch.EditableValidatingObject into Edit mode.

Well, from the ViewModel, we can simply do this.CurrentCustomer.BeginEdit(); it's that easy. However, what you must also do is if you have any nested Cinch.DataWrapper<T> objects, make sure they are put into the correct state. You would do this in your UI Model class as follows, where we simply override the protected virtual void OnBeginEdit() we get from inheriting from Cinch.EditableValidatingObject.

What we need to do is override the Cinch.EditableValidatingObject virtual methods as follows:

#region EditableValidatingObject overrides
///<summary>/// Override hook which allows us to also put any child
/// EditableValidatingObject objects into the BeginEdit state
///</summary>protectedoverridevoid OnBeginEdit()
{
base.OnBeginEdit();
//Now walk the list of properties in the CustomerModel//and call BeginEdit() on all Cinch.DataWrapper<T>s.//we can use the Cinch.DataWrapperHelper class for this
DataWrapperHelper.SetBeginEdit(cachedListOfDataWrappers);
}
///<summary>/// Override hook which allows us to also put any child
/// EditableValidatingObject objects into the EndEdit state
///</summary>protectedoverridevoid OnEndEdit()
{
base.OnEndEdit();
//Now walk the list of properties in the CustomerModel//and call CancelEdit() on all Cinch.DataWrapper<T>s.//we can use the Cinch.DataWrapperHelper class for this
DataWrapperHelper.SetEndEdit(cachedListOfDataWrappers);
}
///<summary>/// Override hook which allows us to also put any child
/// EditableValidatingObject objects into the CancelEdit state
///</summary>protectedoverridevoid OnCancelEdit()
{
base.OnCancelEdit();
//Now walk the list of properties in the CustomerModel//and call CancelEdit() on all Cinch.DataWrapper<T>s.//we can use the Cinch.DataWrapperHelper class for this
DataWrapperHelper.SetCancelEdit(cachedListOfDataWrappers);
}
#endregion

Where the Cinch framework provides a static helper called DataWrapperHelper, which you must use to set the correct edit state of the nested DataWrapper<T> objects; you can use these helper methods:

Where the IEnumerable<DataWrapperBase> wrapperProperties is actually the cachedListOfDataWrappers which was obtained during the object construction.

You do not have to worry about this, Cinch will do this for you providing you do the right thing in the UI Model class. If you are feeling a little lost by all this, do not worry: one of the subsequent articles will walk through how to create a UI Model using Cinch. This article is more about Cinch internals for those that may be interested.

WeakEvent Creation

Before I start talking about how to create WeakEvents, I think this may be a good place to start a small discussion. I imagine there are loads of readers/.NET developers that think Events in .NET are cool. Well, me too, I love events. The thing is, how many of you think you need to worry much about Garbage Collection, and when dealing with events, .NET manages its own memory via the GC right? Well, yeah it does, but Events are one area that are, shall we say, a little gray in .NET.

In the diagram above, there is an object (eventExposer) that declares an event (SpecialEvent). Then, a form is created (myForm) that adds a handler to the event. The form is closed and the expectation is that the form will be released to garbage collection, but it isn't. Unfortunately, the underlying delegate of the event still maintains a strong reference to the form because the form's handler wasn't removed.

In typical applications, it is possible that handlers that are attached to event sources will not be destroyed in coordination with the listener object that attachs the handler to the source. This situation can lead to memory leaks. Windows Presentation Foundation (WPF) introduces a particular design pattern that can be used to address this issue, by providing a dedicated manager class for particular events and implementing an interface on listeners for that event. This design pattern is known as the WeakEvent pattern.

Now if you have ever looked into the Weak Event manager / interface implementation, you will realise it is quite a lot of work and you must have a new WeakEventManager per Event type. This to me sounds like too much work, so I would prefer some other mechanisms, such as have a WeakEvent in the beginning. Better still, maybe have a weak listener that only reacts to the source event if the source of the event is still alive and has not been GC'd.

Raise a WeakEvent<T>

So without further ado, let me show you some handy little helpers that are available within Cinch when dealing with Events, and possibly making them Weak. It is still obviously better to Add/Remove the delegates for an event manually where possible, but sometimes you just do not know the lifecycles of the objects involved, so it is preferable to opt for a WeakEvent strategy.

Firstly, let's use the absolutely brilliant WeakEvent<T> from the very, very talented Daniel Grunwald, who published a superb article on WeakEvents some time ago. Daniel's WeakEvent<T> shows how you can raise an event in a weak manner.

I am not going to bore you with all the code for WeakEvent<T>, but one thing that you should probably get familiar with, if you are not already, is the WeakReference class. This is a standard .NET class, which references an object while still allowing that object to be reclaimed by garbage collection.

Pretty much any WeakEvent subscription/raising of event will use an internal WeakReference class to allow the source of the event or the subscriber to be GC'd.

Anyway, to use Daniel Grunwald's WeakEvent<T>, we can do the following:

Raising the WeakEvent<T>

Listening to WeakEvent<T>

So that is how you could make a WeakEvent<T>, but sometimes it is not your own code and you are not in charge of the Events contained in the code. Perhaps you are using a third party control set. So in that case, you may need to use a WeakEvent subscription. Cinch provides two methods of doing this.

WeakEvent Subscription

Above we saw how to raise a WeakEvent using Daniel Grunwald's WeakEvent<T>, so how about in the case where we want to subscribe to an existing event? Again, this is typically achieved using a WeakReference class to check the WeakReference.Target for null. If the value is null, the source of the event has been garbage collected so do not fire the invocation list delegate. If it is not null, the source of the event is alive so call the invocation list delegate which subscribed to the event.

Cinch provides two methods to do this.

WeakEventProxy

Which is a neat little class which Paul Stovell wrote some time ago. The entire class looks like this:

WeakEvent Subscriber With Auto Un-subscription

I was trawling the internet one day and found this superb article on WeakEvents: http://diditwith.net/PermaLink,guid,aacdb8ae-7baa-4423-a953-c18c1c7940ab.aspx. This links contained some cool code that I have used within Cinch, which not only allows users to create WeakEvent subscriptions, but allows the user to specify an auto unsubscribe callback delegate. In addition, using a small variation to this code, it is possible to make all subscribed event handlers weak. Let's have a quick look at the syntax for both these operations:

As I say, I can not take much credit for this code, it came from the link specified, but I do think it's very handy. We actually use it in production code without too many issues. The only thing I have noticed is that it doesn't play well with the CollectionChanged of ObservableCollection<T>, but then I just use the WeakEventProxy that I also mentioned above that is part of Cinch, and that works just fine.

Mediator Messaging

Now, I do not know about you, but generally, when I work with the MVVM framework, I do not have a single ViewModel managing the whole shooting match. I actually have a number of them (in fact, we have loads). One thing that is an issue using the standard MVVM pattern is cross ViewModel communication. After all, the ViewModels that form an application may all be disparate unconnected objects that know nothing about each other. However, they need to know about certain actions that a user performed. Here is a concrete example.

Say you have two Views one with customers and one with orders for a customer. Let's say the orders view was using a OrdersViewModel and that the customers view was using a CustomersViewModel, and when a customer's order is updated, deleted, or added to that, the Customer view should show some sort of visual trigger to alert the user that some order detail of the customer changed.

Sounds simple enough, right? However, we have two independent views run by two independent ViewModels, with no link, but clearly, there needs to be some sort of connection from the OrdersViewModel to the CustomersViewModel, some sort of messaging perhaps.

This is exactly what the Mediator pattern is all about, it is a simple light weight messaging system. I wrote about this some time ago on my blog, which in turn got made a ton better by Josh Smith / Marlon Grech (as an atomic pair) who came up with the Mediator implementation you will see in Cinch.

So how does the Mediator work?

This diagram may help:

The idea is a simple one, the Mediator listens for incoming messages, sees who is interested in a particular message, and calls each of those that are subscribed against a given message. The messages are usually strings.

Basically, what happens is that there is a single instance of the Mediator sitting somewhere (usually exposed as a static property on the ViewModelBase class) that is waiting for objects to subscribe to it either using:

An entire object reference. Then any Mediator message methods that have been marked up with the MediatorMessageSinkAttribute attribute will be located on the registered object (using Reflection) and will have a callback delegate automatically created.

An actual Lambda callback delegate.

In either case, the Mediator maintains a list of WeakAction's callback delegates. Where each WeakAction is a delegate which uses an internal WeakReference class to check the WeakReference.Target for null, before calling back the delegate. This caters for the fact that the target of the callback delegate may no longer be alive as it may have been Garbage Collected. Any instance of the WeakAction's callback delegates that point to objects that are no longer alive are removed from the list of the MediatorWeakAction's callback delegates.

When a callback delegate is obtained, either the original callback delegate is called or the Mediator message methods that have been marked up with the MediatorMessageSinkAttribute attribute will be called.

Here is an example of how to use the Mediator in all the different possible manners.

Registering for Messages

Using an explicit callback delegate (this is not my preferred option though)

We simply create the correct type of delegate and register a callback for a message notification with the Mediator.

Register an entire object, and use the MediatorMessageSinkAttribute attribute

This is my favourite approach and is the simplest approach in my opinion. You just need to register an entire object with the Mediator and attribute up some message hook methods.

So to register, this is done for you in Cinch, so you don't have to do anything. Simply inherit from ViewModelBase, job done. If you are wondering how this is done, the ViewModelBase class in Cinch simply registers itself with the Mediator like this:

//Register all decorated methods to the Mediator
Mediator.Register(this);

So any method that is marked up with the MediatorMessageSinkAttribute attribute will be located on the registered object (using Reflection) and will have a callback delegate automatically created. Here is an example:

Message Notification

That is very easy to do, we simply use the Mediator.NotifyCollegues() method as follows:

//Use the Mediator to send a Message to MainWindowViewModel to add a new //Workspace item
Mediator.NotifyColleagues<Boolean>("AddCustomerMessage", true);

You can also use the Mediator asynchronously as follows:

Mediator.NotifyColleaguesAsync<Boolean>("AddCustomerMessage", true);

At present, the Cinch ViewModelBase class registers the ViewModel instance with the Mediator, within the ViewModel constructor, and unregisters the ViewModel instance with the Mediator within the Dispose() method.

So any object that subscribes to this message will now be called back by the list of the MediatorWeakAction's callback delegates.

What's Coming Up?

In the subsequent articles, I will be showcasing it roughly like this:

A walkthrough of Cinch, and its internals: II

How to develop ViewModels using Cinch

How to Unit test ViewModels using a Cinch app, including how to test background worker threads which may run within Cinch ViewModels

A demo app using Cinch

That's It, Hope You Liked It

That is actually all I wanted to say right now, but I hope from this article you can see where Cinch is going and how it could help you with MVVM. As we continue our journey, we will be covering the remaining items within Cinch, and then we will move on to see how to develop an app with Cinch.

Comments and Discussions

Read the articles text, it could not be any clearer I feel. There is nothing more I can say, it's all there in the articles text.

Edit:
From what you say you want to do stuff in codebehind? That is exactly the opposite of what the LifetimeEvents are for. They are to allow your VIEWMODEL to run some methods when you attached the LifetimeEvents to certains UserControl/Window events. There is no catering for code behind AT ALL. That is so far removed from what I am trying to show people how to do things with this MVVM framework.

I am trying to get things in the ViewModel where it is all testable.

Sacha Barber

Microsoft Visual C# MVP 2008/2009

Codeproject MVP 2008/2009

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

My business object A derives from your base class "EditableValidatingObject". Then I have a business object B that derives from A.

In the methods GetFieldValues() and RestoreFieldValues() you use the method GetType().GetFields(..). These method does not return the properties of the base class (lets say A)!!! It only returns the public fields of A but not public properties and of course no private properties.

Wouldnt it be better to use the Get Properties method instead? Like this:

I just ran into a little quirk. It seemed that the property setters of the DataWrapper properties were not getting called on a CancelEdit(). Stefan's proposal remedies this problem as well. So, instead of the DataWrapper's fields getting set directly, now its properties get set via their setter.

The added benefit of this change is that NotifyPropertyChanged() and NotifyParentPropertyChanged() get called as well now, because DataWrapper.DataValue's property setter takes care of that.

Then I thought... wait a minute didn't Sacha already change the code base... And you did...

Sacha Barber wrote:

I have run this and tested it, its seems ok so I have changed Cinch to do it this way.

So what's happening? Turns out my DataWrappers are defined in the Model, not in the ViewModel. So they inherit EditableValidatingObject, not EditableValidatingViewModelBase. Copy -> Paste -> Fixed
Works like a charm now.

BTW: you could remove the line NotifyParentPropertyChanged() from DataWrapperHelper.SetCancelEdit(), because the setter now calls it for you. On a side note: what is the reasoning behind calling NotifyParentPropertyChanged() from SetBeginEdit() and SetEndEdit()?

/// <summary>
/// This stores the current "copy" of the object.
/// If it is non-null, then we are in the middle of an
/// editable operation.
/// </summary>
private Dictionary<string, object> _savedState;

BeginEdit() sets this field and EndEdit() clears it. However, CancelEdit() does not clear it.

Ah finally. Yeah it took me a long long long time to write this up and think about what was best, but I have to say it works a treat, I am just about to come out with a code generator for it this weekend. You can knock up a very complete viewmodel in minutes, all you then have to do is add logic and validation faults.

So in your ViewModel you can use the ICommand parameter, and cast it to EventParameters and it should give you the args you wanted.

If you would like to supply some arbitary Command Parameter say via a Binding, this would not suit the SingleEventCommand or the EventCommander ideas, as these fire a command based on some RoutedEvent, so should ONLY ever supply the routedEventArgs as ICommand parameter.

I mean to be honest EventCommander is more flexable that SingleEventCommand, but SingleEventCommand is good when there is only 1 command and you don't need the event args.

Sacha Barber

Microsoft Visual C# MVP 2008/2009

Codeproject MVP 2008/2009

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

Thx for a great article and really great framework. I'm brand new in MVVM and have started to develop a small "have-fun" application. But I keep getting and error when trying to create an object (MainWindowViewModel) that inherits from ViewModelBase, giving me this exception:
System.TypeInitializationException was unhandled
Message="The type initializer for 'Cinch.ViewModelBase' threw an exception."
Source="Cinch"
TypeName="Cinch.ViewModelBase"
StackTrace:
at Cinch.ViewModelBase..ctor()
at EHDS.ViewModels.ViewModels.MainWindowViewModel..ctor() ...

It seems my unity isn't setup correctly. I get messages that there couldn't be found schema information for the "unity" element (and all other the "unity" elements children) in the app.config. I have added the unity dll's to refrences of the project. Anyone got an idea?

It is talking about the 1 Service you MUST have in your actual WPF app.

So you need to make sure YOUR WPF APP has an instance of the IUIVisualiser service, and make sure that is correctly marked up in the Unity section within the App.Config of both your actual WPF app and the test app. Have a look at the Cinch demo app you will see what I mean.

Sacha Barber

Microsoft Visual C# MVP 2008/2009

Codeproject MVP 2008/2009

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

No its not dumb at all actually. And I have to say it looks totally ok to me.

I know the code works as its working for me and the demo app, it must be something dumb. Have you referenced all the required Unity items I wonder.

Here is what I think you need to do

1. Make sure your app references same Dlls as demo app
2. Maybe include CInch source code in your app and reference it via a project reference and step into ViewModelBase class constructor to see what is going on with Unit container.

As I say it looks ok, and I know it works it has to be something silly

Sacha Barber

Microsoft Visual C# MVP 2008/2009

Codeproject MVP 2008/2009

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

Thank you. I'm also getting more and more convinced it's something silly. I have tried taking the unity dll from the demo, added them to my gui projects references and tried adding the cinch source project to my solution, but no luck. I'll try stepping into the cinch viewmodelbase, haven't tried that yet.

Still the unity elements isn't recognized by visual studios xml-parser, which leads me to think there something wrong with my references.

EDIT:
Tried single-stepping through the unity code in viewmodelbase. I get a container, with one registered type. This line: section.Containers.Default.Configure(UnitySingleton.Instance.Container);
throws the exception.
The the types element, contains 1 items. The item has _key ":Cinch.IUIVisualizerService, Cinch" and maps to "EHDS.GUI.WPFUIVisualizerService, EHDS.GUI". I really don't see whats wrong

to hold the collection of orders for the customer. But suppose I also wanted to have a property on the OrderModel to hold a reference back to the customer who placed the order. Do you recommend doing that with a DataWrapper like you would with a standard .Net built-in type? Just something as simple as:

private Cinch.DataWrapper<CustomerModel> customer

and the associated code in the constructor, public property, changeArgs, etc.? Thanks for your help!