This app is built on Visual Studio 2008 SP1, SQL Server 2008, Silverlight 2.0 and the Silverlight Toolkit using C#.
The finished code for this post can be found here.
Steps:
1. Open the solution for the code found here.
2. Review the code for Page.xaml and its code behind and the code for ViewModel.cs. A ViewModel object is instantiated as a static resource for the Page User Control. The ViewModel object has two string properties TextProperty and CopiedTextProperty that are both bound to text blocks to display their values. When the user clicks the Copy Text button, the buttons event handler calls a function on the ViewModel resource to copy the value in the TextProperty to the CopiedTextProperty. As the ViewModel implements INotifyProprtyChanged and the CopiedTextProperty is bound to a text block in the Page user control the text block display is automatically updated – the joy of data binding in Silverlight!
3. Run the app and check that it’s working

OK so my goal is to have the click event be handled directly by a function in the ViewModel class that can declaratively be associated with the button in the Page.xaml file, with zero wire up code in the Page.xaml.cs file. To do that we need a few infrastructure pieces. We will add these now and I will explain what each does at each step.
4. To have a function be passed around in C# we need to declare a delegate or Action<…> to refer to it. We want to have an object that can hold that function reference so we can refer to it easily without needing a reference to the object in which the function resides. This is effectively commanding. In Silverlight 2.0 the ICommand interface is provided for us but prior to Silverlight 2.0 we had to define our own commanding interface. Add a class to the Silverlight project named DelegateCommand and implement the ICommand interface.
5. Add the following to the DelegateCommand class to declare the member variable to hold the delegate and provide a constructor with the delegate as a parameter
private Action<object> handler;
public DelegateCommand(Action<object> functionDelegate)
{
handler = functionDelegate;
}
6. Add the following line to the Execute function in DelegateCommand to execute the delegate.
handler.Invoke(parameter);
7. Add a class file called ICommandProvider to the Silverlight project change the class to an interface.
8. Add the following definition to the ICommandProvider interface
ICommand GetCommand(string key);
9. Add the following line to the top of the ViewModal.cs file
using System.Collections.Generic;
10. Replace the existing ViewModel constructor with the following code
private Dictionary<string, ICommand> commandDictionary = new Dictionary<string, ICommand>();
public ViewModel()
{
commandDictionary.Add("GetTextButtonClick", new DelegateCommand(GetTextButtonClick) );
}
public void GetTextButtonClick(object parameter)
{
this.CopyText();
}
This code adds a member variable Dictionary to hold references to the DelegateCommands for this view model that will be declaratively associated with XAML controls. We are only going to have one delegate but I thought I’d include this code as a nice to have.
The constructor then adds a commandDictionary entry with a known key and a DeleteCommand object referencing the GetTextButtonClick function declared after the constructor.
11. Change the ViewModel class to implement the ICommandProvider interface
12. Replace the contents of the GetCommand function in the ViewModel class with the following line
return commandDictionary[key] ?? new DelegateCommand( (o)=> {});
This line returns the delegateCommand object in our commandDictionary refered to by the provided key if it exists or an empty delegate that does nothing if the key cannot be found in the dictionary.
13. Build and run the application. HEY HOLD ON! We haven’t decoupled the XAML code behind button click event handler. That’s right – we have put in the infrastructure that is needed to be able to develop the attached behavior. Now we have the infrastructure in place we can develop and use our attached behavior.
14. Add a class called ClickBehavior to the Silverlight project and make the class static (this is part of the way attached properties are declared)
15. Add the following code to the ClickBehavior class
public static DependencyProperty ClickCommandProperty =
DependencyProperty.RegisterAttached("ClickCommand", typeof(string),
typeof(ClickBehavior),
new PropertyMetadata(new PropertyChangedCallback(ClickCommandChanged)));
public static void SetClickCommand(DependencyObject sender, string command)
{
sender.SetValue(ClickCommandProperty, command);
}
public static void ClickCommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
}
The first line of code registers the ClickCommand attached property, the first function provides the setter function for the attached property and the second function provides the event handler for when the value of the attached property changes.
We will add logic to the ClickCommandChanged event handler to hook up the ViewModel delegate to the click event of the button this attached property will be assigned to.
16. Add the following code to the ClickCommandChanged event handler
Button button = sender as Button;
if (button != null)
{
if (e.NewValue != null && e.OldValue == null)
button.Click += new RoutedEventHandler(uiButton_Click);
else if (e.NewValue == null && e.OldValue != null)
button.Click -= new RoutedEventHandler(uiButton_Click);
}
This code takes the reference for the sender (which is the XAML control that the attached property is assigned to) and checks it is a button. When assigning a value to the ClickCommand attached property we are adding an event handler to the buttons click event. We will add that event handler next.
17. Add the following code below the ClickCommandChanged event handler
static void uiButton_Click(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
string commandKey = (string)button.GetValue(ClickBehavior.ClickCommandProperty);
ICommandProvider provider = null;
DependencyObject element = button as DependencyObject;
while (element != null)
{
FrameworkElement fe = element as FrameworkElement;
if (fe != null)
{
object result = fe.Resources["ViewModel"];
if (result != null)
{
provider = result as ICommandProvider;
break;
}
}
element = VisualTreeHelper.GetParent(element);
}
if (provider != null)
{
ICommand command = provider.GetCommand(commandKey);
command.Execute(sender);
}
}
This event handler retrieves the command name – the value assigned to the ClickCommand attached property, finds the ViewModel object in the visual tree, calls the GetCommand function on the ViewModel object and then calls the Execute function on the DelegateCommand that is returned. This is where the magic happens!!!!! The last thing to do is use the attached property to associate the button with the ViewModel GetTextButtonClick command.
18. Build the application
19. Replace the click attribute with the following attached property attribute on the button control in Page.xaml
myProj:ClickBehavior.ClickCommand="GetTextButtonClick"
20. Delete the Button_Click event handler in the Page.xaml.cs file
21. Place a break point in the GetTextButtonClick function in ViewModel.cs and run the application
22. Enter some text and click the Copy Text button.
23. The breakpoint will be hit in the GetTextButtonClick function in ViewModel.cs. If you let it run the application will complete with the same result (the text being copied) as when we used the code behind in the Page.xaml.cs file.
CONGRATULATIONS! You have an MVVM architecture application with separated View and View Model.
What have we done?
Added infrastructure to enable the Commanding pattern to be used to wrap a delegate function
Defined an attached property to handle the assigning of a named command (a delegate function) with the click event of a button control
Why do this?
Some reading this post would say – WHY ON EARTH WOULD I WANT TO DO ALL THIS TO MOVE THE CODE FOR A SIMPLE BUTTON CLICK?????!!!!!!!!
Because by implementing the commanding mechanism and an attached behavior like this, it’s available for re-use and is hooked up just by declaration in XAML
As your app development effort scales and you re-use these – you have a true separation of concerns for your development efforts and gain great quality efficiencies.
Your UI can be developed completely separately from your logic in the view model. Your view model can be tested without UI being developed; i.e. it enables Test Driven Development and/or distributed Teams working synchronously on separate business functions/components with less stepping on each other’s toes or designers wrecking the use of the view when it’s already had event handlers developed and hooked up via code behind.
Other than the declaring the view model event handler (which you would have to do in the user control code behind anyway), adding a DelegateCommand object to the commandDictionary in the view model and assigning the command key to the ClickCommand attached property on whatever button you want (which you would have to declare the click handler attribute in XAML anyway), you don’t need any more code to scale out the use of this technique.
Many other attached behaviors can be written for any other standard control events (MouseEnter, MouseLeave, SelectionChanged, TextChanged, KeyDown, etc…..) to enable the moving of the event handler to the view model.
Using attached behaviors enables a cleaner logical design and software development experience in my opinion and allows people with less architecture experience to understand and use such a pattern, rather than introducing them into using the Composite Application Guidance and many more design concepts, which they may not e ready to adopt or have no need of due to the simplicity of the application they may be developing. Once they are used to this stepping stone, use of the CAG for complex composite apps is much more achievable for a team that hasn’t used it – if they want to adopt it.