Mediator v2 for MVVM WPF and Silverlight applications
This last 2 weeks, us WPF Disciples have been talking a lot about the Mediator pattern for MVVM applications. Me and Josh Smith revised my previous Mediator implementation and found some problems with it.
Problem: There was a memory leak. Once a Mediator subscribes for one or more messages it would be kept in memory since the Mediator was holding a reference to the ViewModel.
Solution: We could have just exposed an unregister method so that when you call this method the Mediator would release the instance of the ViewModel. But sometimes it is hard to know when a ViewModel is going to die… So we went a step further and created the WeakAction. The WeakAction stores the instance of the ViewModel in a WeakRefence thus the ViewModel can be garbage collected without any problem and once it does get garbage collected the Mediator automatically removes that ViewModel registration from the list.
While we were at it we PIMPED the Mediator API
We added 2 approaches to subscribe to the Mediator and we also added support for (thanks to David Anson suggestion) strongly typed parameters.
So now the Mediator offers 2 methods of registration, a declarative way of registering and an imperative way as well.
The Declarative approach. (Supported in WPF and Silverlight)
This approach uses attributes so that you can decorate the messages that act as subscribers for messages.Here is an example
1: /// <summary>
2: /// Subscribe to Message1
3: /// </summary>
4: /// <param name="message">The message to be passed</param>
5: [MediatorMessageSink(MediatorMessages.Message1, ParameterType = typeof(SomeData))]
6: public void Test(SomeData data)
7: {
8: MessageBox.Show(data.Text + "\nReceived by: ColleagueA");
9: }
So you just have to decorate your method with MediatorMessageSink attribute and the Method will get invoked every time a message is broadcasted via the Mediator.
As you can see the Mediator also supports strongly typed parameters. In order to do so you have to specify the ParameterType property on the attribute as shown in the sample code above. You can pass 0 or 1 parameters. If you don’t have any parameters just ignore the ParameterType (since this is an named Property and you can just not set it )
When using the declarative approach you must register the instance of the ViewModel to the Mediator. This is just one line of code in the ViewModel constructor. Here is how you do that
1: public ColleagueA()
2: {
3: //Register all decorated methods to the Mediator
4: Mediator.Register(this);
5: }
This will inspect all methods of the ViewModel and look for the MediatorMessageSink attribute and register the appropriate methods to the Mediator. If you are going to have a base class for the ViewModels in your project and you can put this in the constructor of your base class. As simple an that.
The Imperative approach. (Supported in WPF ONLY)
If you do not want to use the attribute based registration we offer an imperative approach where you specify a method to be registered to a specific message. This implementation is exactly as it was in the old Mediator yet now it supports strongly typed parameters.
Here is how you can use this in your code
1: public ColleagueC()
2: {
3: //Register a specific delegate to the Mediator
4: Mediator.Register(MediatorMessages.Message1,
5: (Action<SomeData>)
6: delegate(SomeData x)
7: {
8: Test = x.Text;
9: MessageBox.Show(x.Text + " \nReceived by: ColleagueC");
10: });
11: }
This method is supported in WPF only since in Silverlight you cannot call an anonymous method (via reflection). If you try to use this method in Silverlight you will get an InvalidOperationException saying “This method is not supported in Silverlight”.
Conclusion
I packaged the Mediator in a class library so that you can go ahead and add a reference and reuse this library in your day to day projects.As always feedback is much appreciated.
Karl and his XAML Power Toys
Karl Shifflett has done a great job in his new XAML Power Toys. This tool can really speed up development big time. I am simple amazed at the ideas that this guy has. The actual tool really does work… I use it every day and it makes my development so much faster. So guys, if you do not have it just go and get it.
Silverlight: Binding and Threading == Cat and Dog
Introduction
Let me start by thanking Ian Griffiths for the brilliant course that he delivered to me in London this week on Silverlight. Ian you’re the man!!! Ok having said that we can now start
Just like in WPF, threading and databinding in Silverlight have a Cat – Dog relationship. This is due to the fact that when a binding notification is raised from a separate thread than the Dispatcher thread, an exception is thrown. The exception is thrown because the binding is trying to modify the a UI element from a separate thread than the Dispatcher thread. In Silverlight this is even a bit worse than it is in WPF because an exception is raised even when the notification is from an INotifyPropertyChanged. Another miss leading thing in Silverlight is that, the exception thrown when a binding notification is raised from a separate thread is of type System.UnauthorizedAccessException (you can see this in the Visual Studio Output window). Hmmm … We WPF guys are used to see the InvalidOperationException for this but anyway…
Ok so till now we determined that both INotifyPropertyChanged and INotifyCollectionChanged will explode if they raise the binding notification from a separate thread than the UI thread so let’s see how to work around this.
In WPF one can get the Dispatcher instance by calling Application.Current.Dispatcher or by saying Dispatcher.CurrentDispatcher but guess what; both of these are not included in Silverlight. Don’t worry we still can get Mr. Dispatcher, we need to call the Application.Current.RootVisual.Dispatcher (keeping in mind not to call RootVisual from a seperate thread than the Dispatcher thread otherwise BAMMMM).
Brilliant, we have the dispatcher but guess what the only method that you can see (in the VS intellisense) in the Dispatcher is BeginInvoke !! This will not help much since we need a CheckAccess method that can check for us if the executing thread is the dispatcher thread. After drilling into the Dispatcher class, I found that a CheckAccess method actually exits in the Dispatcher class but for some strange reason it is decorated with this attribute -> [EditorBrowsable(EditorBrowsableState.Never)] to hide it from us developers. I guess this means that it is subject to change in the very near future …
Anyway, now that we know how to get the Dispatcher instance and how to check if the executing thread is the dispatcher thread we can get to work. Lets’ start by fixing the INotifyPropertyChanged issue.
Fixing INotifyPropertyChanged
This will be quite easy, we will need to make the object raise the binding notification on the dispatcher thread. I created a base class that will do this for you… It is very simple have a look yourself.
/// <summary>
/// Base class for objects that need to raise property change notification from seperate threads
/// </summary>
public abstract class ThreadableBindableObject : INotifyPropertyChanged
{
private Dispatcher currentDispatcher;
/// <summary>
/// default constructor
/// Here we must get the Dispatcher object
/// </summary>
public ThreadableBindableObject()
{
if (Application.Current != null &&
Application.Current.RootVisual != null &&
Application.Current.RootVisual.Dispatcher != null)
{
currentDispatcher = Application.Current.RootVisual.Dispatcher;
}
else // if we did not get the Dispatcher throw an exception
{
throw new InvalidOperationException("This object must be initialized after that the RootVisual has been loaded");
}
}
#region INotifyPropertyChanged Members
/// <summary>
/// Event raised to notify listeners that a property changed
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// raises the PropertyChanged on the dispatcher thread
/// This will only switch to the Dispatcher thread if the Dispatcher is available via the RootVisual
/// </summary>
/// <param name="propertyName">The property name to raise the event</param>
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
//check if we are on the UI thread if not switch
if (currentDispatcher.CheckAccess())
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
else
currentDispatcher.BeginInvoke(new Action<string>(OnPropertyChanged), propertyName);
}
}
#endregion
}
So basically this base class will go ahead and implement the INotifyPropertyChanged interface for you and make sure that before the PropertyChanged event is raised we are on the Dispatcher thread. One would ask why are we getting the dispatcher instance in the constructor of the object, well the answer is that, we cannot get the Dispatcher instance from the OnPropertyChanged method because that method will be called from non dispatcher threads and if you call the Application.Current.RootVisual from a non dispatcher thread BAMMM… everything explodes because you are trying to access a UI element from a non dispatcher thread. Ok so now that we have this class we can go ahead and use it by inheriting from it; something like this I would say
public class Person : ThreadableBindableObject
{
private string name;
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged("Name");
}
}
private string surname;
public string Surname
{
get { return surname; }
set
{
surname = value;
OnPropertyChanged("Surname");
}
}
}
Fixing INotifyCollectionChanged
When it comes to the INotifyCollectionChanged we want to avoid to re invent the wheel and implement the INotifyCollectionChanged interface ourselves so what we are going to do is to inherit from the ObservableCollection<T> and override the base methods for the Insert, Remove, Clear and Set. We will also need to override the OnPropertyChanged. This is nothing new, Beatriz Costa the WPF Queen, did this a while ago in the WPF world so; NO, I am not inventing anything here I am just being a messenger
So here is the code for the new ObservableCollection… I called it ThreadableObservableCollection<T> so that it sounds complex
/// <summary>
/// Collection that supports INotifyCollectionChanged notification from seperate threads
/// </summary>
/// <typeparam name="T">The type of object to store in the collections</typeparam>
public class ThreadableObservableCollection<T> : ObservableCollection<T>
{
private Dispatcher currentDispatcher;
/// <summary>
/// default constructor
/// Here we must get the Dispatcher object
/// </summary>
public ThreadableObservableCollection()
{
if (Application.Current != null &&
Application.Current.RootVisual != null &&
Application.Current.RootVisual.Dispatcher != null)
{
currentDispatcher = Application.Current.RootVisual.Dispatcher;
}
else // if we did not get the Dispatcher throw an exception
{
throw new InvalidOperationException("This object must be initialized after that the RootVisual has been loaded");
}
}
protected override void InsertItem(int index, T item)
{
if (currentDispatcher.CheckAccess())
base.InsertItem(index, item);
else
currentDispatcher.BeginInvoke(new Action<int, T>(InsertItem), index, item);
}
protected override void ClearItems()
{
if (currentDispatcher.CheckAccess())
base.ClearItems();
else
currentDispatcher.BeginInvoke(new Action(ClearItems));
}
protected override void RemoveItem(int index)
{
if (currentDispatcher.CheckAccess())
base.RemoveItem(index);
else
currentDispatcher.BeginInvoke(new Action<int>(RemoveItem), index);
}
protected override void SetItem(int index, T item)
{
if (currentDispatcher.CheckAccess())
base.SetItem(index, item);
else
currentDispatcher.BeginInvoke(new Action<int, T>(SetItem), index, item);
}
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (currentDispatcher.CheckAccess())
base.OnPropertyChanged(e);
else
currentDispatcher.BeginInvoke(new Action<PropertyChangedEventArgs>(OnPropertyChanged), e);
}
}
As you can see there is nothing to it. We are just overriding the base methods Insert, Remove, Clear and Set so that we make sure that they will get called on the Dispatcher thread. These methods are the methods that raise the CollectionChanged event so by forcing them to run on the Dispatcher thread we are ensuring that the binding will potentially work (hihi … what a paradox). We are also doing this for the OnPropertyChanged method of course.
Conclusion
Yea, the conclusion is threading can be pain full especially when dealing with UI but that’s life
Debug Javascript in a Silverlight application
One very handy feature of Visual Studio 2008 is debugging in Javascript. I beleive that working with javascript in VS2008 has became simply brilliant!
Having said that I was building a silverlight application and I tried to do a breakpoint in my Javascript code and guess what…. It did not work !
Ian Griffths (my Silverlight teacher
) pointed out to me that this problem was caused by having Silverlight debugging selected in Visual Studio… So in order to debug Javascript you must go to the website Property Pages -> Select “Start Options” and uncheck the Silverlight checkbox in the Debuggers sectionas shown in the image below
If this still is not working for you check your Internet Explorer settings . Basically you MUST have the “Disable Script Debugging” in IE unchecked. To find out if this is set correctly go to the “Tools” menu in IE -> “Internet Options” -> ”Advanced” and you should see it now. This must be unchecked.
How can I get the DataGrid control for Silverlight 2 Beta 1 to show up in Blend?
So, let me start by saying this, I am not a blend guru. I never use blend, I prefer Visual Studio. I was showing off Blend 2.5 March 2008 Preview to the designers at work and I noticed that the Silverlight DataGrid was not showing up in the list of controls in blend. Then I remembered that the Datagrid control for Silverlight 2 Beta 1 is in the System.Windows.Controls.Data dll which is not added as a reference by default in Silverlight projects.
So how can one make the Datagrid control show up in blend for a Silverlight project?
The answer is very easy. You have to add a reference to the System.Windows.Controls.Data dll. To do this right click on the References folder in blend and select Add Reference (as shown in the image below)
An open file dialog should pop up. The System.Windows.Controls.Data dll is located in the folder C:\Program Files\Microsoft SDKs\Silverlight\v2.0\Libraries\Client\. Enter that path in the address bar and a list of Dll should popup. Select the System.Windows.Controls.Data dll and you’re done
Now that you added the reference to the System.Windows.Controls.Data dll, the Datagrid control should appear in blend.
If you are going to use the DataGrid control for Silverlight I would suggest that you read this very useful blog post
Have loads of fun with Silverlight…
Generic.xaml in Silverlight Beta1 for WPF developers
I woke up early this morning and decided to play around with Silverlight…. I love Silverlight it makes me feel like I am developing in WPF yet Cross Browser and Cross Platform…. can it get better than that???
Yet, this morning I had to swear a bit !
Generic.xaml xmlns
I was building a Silverlight custom control (as usual that the first thing I try out in a new platform
) and I found a post that helped me a lot. The first problem that I found was Visual Studio does not have a template for a ResourceDictionary for Silverlight.
As you all know in order to build a custom control Generic.Xaml is one of the most important things to do. Generic.Xaml would contain the UI of the custom controls.
Yet thanks to the post I just mentioned I got through this by create a Text File (naming it generic.xaml) and setting the Build Action to Resource. You must also clear all other fields… something like this

I said ok, I have the generic.xaml all set up now all I need to do is to create a Style for the control that will act as the UI for my new Custom control. First thing I did was to create an xmlns declaration so that I can style my control. something like this
xmlns:local="clr-namespace:SilverlightApp"
As you can see I did not add the assembly part in this because I said since the generic.xaml is in the same project of the control class I would not need it. At least that is what you would do if you are a WPF developer. But guess what I ran the application and BAMMMM!!! I got a AG_E_UNKNOWN_ERROR. This is a nice error to get in 7 o clock in the morning
I started looking around to try and translate this error and I found a very helpful post. Yet still, I could not find the source of the problem… Then I tried something out, just to say that I tried it… basically I added the assembly part in my generic.xaml xmlns declaration… something like this
xmlns:local="clr-namespace:SilverlightApp;assembly=SilverlightApp"
And Guess what… It worked!!!
For me this is quite crazy because I never had to do such a thing in WPF. Actually if you try to do that in WPF you would start getting an error because the generic.xaml is in the same assembly of the control you are trying to reference. But anyway, Silverlight is still BETA and I am more than sure that this will be fixed in the near future.
The ResourceDictionary.MergedDictionaries
Ok so with the xmlns problem fixed, I was hoping to find no other surprise but after a minute I got another one!!!
Usually when one is building a controls library you would create a ResourceDictionary for each control so that the generic.xaml would not get cluttered. And then you merge all dictionaries in the generic.xaml by using the ResourceDictionary.MergedDictionaries something like this…
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/AvalonControlsLibrary;component/Themes/Brushes.xaml"/>
<ResourceDictionary Source="/AvalonControlsLibrary;component/Themes/DatePicker.xaml"/>
</ResourceDictionary.MergedDictionaries>
But guess what. There is no such thing YET in silverlight ![]()
so you have to put all the resources for the controls in the generic.xaml. I didn’t find a workaround for this yet but I will update this post if/when I do.
Last word
Silverlight is really cool. Don’t let small things like this get in the way. I am more than sure that issues like this will be fixed in the near future…. I remember when WPF was still in Beta there where similar things. The only difference with Silverlight is that there is already WPF and people expect that Silverlight has the same capabilities. Eventually this will happen but for now we must wait
Last 2 words – Silverlight Rocks!





