Facebook Like Box

Main Menu

Event to Command binding using Attached properties in plain WPF without any extra dependancy

When you are developing your application in WPF using MVVM, many times you feel need for handling events in View Model. No doubt the Expression blend interactivity libraries included in Expression blend SDK provide a very simple way to achieve this using behaviors. but what if you don't have such possibility. Then It is NOT a dead end, there are 

 other ways through which you can achieve the same functionality.

I will explain such example on DatePicker in WPF. DatePicker has an event named "CalendarOpened" which is fired when Calender popup is being opened. I will bind this event to a Command in viewmodel.

This example uses Attached properties to achieve this functionality. Attached properties are used to add some extra functionality in existing WPF controls. 

First of all I will write a behavior to register "CalendarOpened" event for a given DatePicker

1- The Attached Property 

public class DateControlBehavior
{
  #region Attached property
  public static ICommand GetCalenderOpenCommand(DependencyObject obj)
  {
  	return (ICommand)obj.GetValue(CalenderOpenCommandProperty);
  }
  public static void SetCalenderOpenCommand(DependencyObject obj, ICommand value)
  {
  	obj.SetValue(CalenderOpenCommandProperty, value);
  }
  // Using a DependencyProperty as the backing store for CalenderOpenCommand. This enables animation, styling, binding, etc...
  public static readonly DependencyProperty CalenderOpenCommandProperty =
  DependencyProperty.RegisterAttached("CalenderOpenCommand", typeof(ICommand), typeof(DateControlBehavior), new PropertyMetadata(null,OnCalenderOpened));
  #endregion
  #region Attached property handler
  private static void OnCalenderOpened(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
	var datePicker = d as DatePicker;
	if (datePicker != null)
	{
	  if (e.NewValue != null)
	  {
		//attach event handler
		datePicker.CalendarOpened += datePicker_CalendarOpened;
	  }
	  else
	  {
		//detach event handler
		datePicker.CalendarOpened -= datePicker_CalendarOpened;
	  }
	}
  }
  ///
  /// Event handler for Calender Opened event.
  ///
  ///
  ///
  static void datePicker_CalendarOpened(object sender, RoutedEventArgs e)
  {
	ICommand command = GetCalenderOpenCommand(sender as DependencyObject);
	if (command != null)
	{
	  if (command.CanExecute(e))
	  {
		//executes a command
		command.Execute(e);
	  }
  	}
  }
  #endregion
}

The above class is a behavior for adding CalenderOpen event to command binding functionailty to any existing DatePicker. The region "Attached Property" is quite simple and in Visual studio you can add this template of code by just entering "propa" and then pressing Tab key 2 times.

The region "Attached property handler" is the section where the actual event is being attached. This function is called each time the AttachedProperty "CalenderOpenCommand" value is changed. In this event handler the DependancyObject passed will be a DatePicker. and "DependancyPropertyChangedEventArgs.NewValue" would be the command with which binding is being done. After some basic checks, the CalenderOpened event handler is registered which is "datePicker_CalenderOpened". In this event handler the Command of ViewModel is retreived through "GetCalenderOpenCommand" and is checked if the command can be executed or not using "CanExecuteMethod" and finaly the command is executed. Thats all you need to do for attaching Event to Command. Now on next page we will see how to use this code using Commands in your view model.

Add comment


Security code
Refresh