Friday, October 5, 2012

Event Markup Extensions - WPF 4.5 RC New Features

WPF 4.5 RC has a lot of very exciting new features. In this post we are going to discussion one feature amongst them. This feature is Markup Extensions for Events. Basically this is to solve one very long standing problem with the framework. Button based controls have a property called Command. We can bind this to an ICommand in the DataContext. This property uses CanExecute of the source ICommand to enable / disable the target button. The framework uses ICommand.Execute to execute the logic based on the ClickMode of the button.

Developers have long felt the absence of the ability to write testable event handlers for other events for a FrameworkElement. Third party libraries have provided different solutions to provide this functionality. MVVM Light has a feature called EventToCommand, which allows binding of an ICommand from the DataContext to the event.

WPF 4.5 Markup Extensions are provided to write testable event handlers outside the code behind without depending on any external libraries. In this post we will be discussing how easy it is to create such markup extensions. If you need a refresher on MarkupExtensions, just have a quick peek here.

http://www.shujaat.net/2010/07/wpf-markup-extensions.html

Let's create a simple WPF Window. It just has a Button occupying whole display area. Look at how we have assigned MouseEnter event.

Since this is in curly brackets {}, this must be a markup extension based on XAML standard. But this is the first time, you might have seen one being used to assign to an event.

The markup extension just need to return the handler for the specified event. Just have a look below how simple can the ProvideValue method of MarkupExtension be.

As discussed above, the runtime uses ProvideValue method to get the handler of the specified event. The actual handler would be execute when the actual event is raised.

Using DataContext in Event Markup Extension
Having an isolated method is of no great value if we cannot pass any parameters from DataContext to the event markup extension handler.

Let's update the view to use the two properties as follows:

Here we have just added two TextBlock(s). Their Text properties are bound to Source and Target properties from DataContext. The Source property has a hardcoded value "Main Title".

Let's run the application now. The view is displayed as follows:


Now let's hover the mouse over the button. This would cause the handler in the markup extension get executed. This would copy the value of Source property into Target property. The view should be updated as follows:


Download

2 comments:

Anonymous said...

You said that "developers have longed for the ability to write testable event handlers for other events (besides Click ?) for a FrameworkElement. Third party libraries have provided different solutions to provide this functionality."

What are the other libraries, besides MVVM Light, that have provided different solutions for this functionality ?

Muhammad Shujaat Siddiqi said...

I was basically referring to the libraries using the blend's interactivity behaviors and you have correctly pointed out MVVM Light. MVVM Light provides EventToCommand. You can also find ActionMessage for Caliburn.