Looking for a WPF job??

Hey there you WPF junkies…

Infusion Development (the company I work for) are looking for people strong in WPF. If you are looking for such a position you can contact smenezes@infusion.com .

P.S Ignore this post if you are not interested 🙂 Had to write this post to please my HR manager and make her approve my vacation leave 😀 haha

Advertisements

How to get the EventArgs as a CommandParameter using the AttachedCommandBehaviour

I have been asked many times how can I get the event args as a command parameter when using the AttachedCommandBehaviour.

Well the library does not support such a feature. I can do that yet I feel like the EventArgs should not flow down to the ViewModel because as such that is a UI thing… Yet in some case (such as for example if you want to set the Handled property to true of the Event args) this is needed.

I decided not to add this in the library yet I am gonna show how one can get this to work with some Attached Behavior.

The idea is to have a Attached Dependency property that handles the event and stores the last Event Args in another Attached Dependency Property. Here is the code to do so

   1: public class MouseEventArgsHandler

   2: {

   3:     #region LastMouseEventArgs

   4:  

   5:     /// <summary>

   6:     /// LastMouseEventArgs Attached Dependency Property

   7:     /// </summary>

   8:     public static readonly DependencyProperty LastMouseEventArgsProperty =

   9:         DependencyProperty.RegisterAttached("LastMouseEventArgs", typeof(MouseButtonEventArgs), typeof(MouseEventArgsHandler),

  10:             new FrameworkPropertyMetadata((MouseButtonEventArgs)null));

  11:  

  12:     /// <summary>

  13:     /// Gets the LastMouseEventArgs property.  This dependency property 

  14:     /// indicates ....

  15:     /// </summary>

  16:     public static MouseButtonEventArgs GetLastMouseEventArgs(DependencyObject d)

  17:     {

  18:         return (MouseButtonEventArgs)d.GetValue(LastMouseEventArgsProperty);

  19:     }

  20:  

  21:     /// <summary>

  22:     /// Sets the LastMouseEventArgs property.  This dependency property 

  23:     /// indicates ....

  24:     /// </summary>

  25:     public static void SetLastMouseEventArgs(DependencyObject d, MouseButtonEventArgs value)

  26:     {

  27:         d.SetValue(LastMouseEventArgsProperty, value);

  28:     }

  29:  

  30:     #endregion

  31:  

  32:     #region HandleMouseDoubleClick

  33:  

  34:     /// <summary>

  35:     /// HandleMouseDoubleClick Attached Dependency Property

  36:     /// </summary>

  37:     public static readonly DependencyProperty HandleMouseDoubleClickProperty =

  38:         DependencyProperty.RegisterAttached("HandleMouseDoubleClick", typeof(bool), typeof(MouseEventArgsHandler),

  39:             new FrameworkPropertyMetadata((bool)false,

  40:                 new PropertyChangedCallback(OnHandleMouseDoubleClickChanged)));

  41:  

  42:     /// <summary>

  43:     /// Gets the HandleMouseDoubleClick property.  This dependency property 

  44:     /// indicates ....

  45:     /// </summary>

  46:     public static bool GetHandleMouseDoubleClick(DependencyObject d)

  47:     {

  48:         return (bool)d.GetValue(HandleMouseDoubleClickProperty);

  49:     }

  50:  

  51:     /// <summary>

  52:     /// Sets the HandleMouseDoubleClick property.  This dependency property 

  53:     /// indicates ....

  54:     /// </summary>

  55:     public static void SetHandleMouseDoubleClick(DependencyObject d, bool value)

  56:     {

  57:         d.SetValue(HandleMouseDoubleClickProperty, value);

  58:     }

  59:  

  60:     /// <summary>

  61:     /// Handles changes to the HandleMouseDoubleClick property.

  62:     /// </summary>

  63:     private static void OnHandleMouseDoubleClickChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

  64:     {

  65:         Control control = d as Control;

  66:         if (control != null)

  67:         {

  68:             if ((bool)e.NewValue)

  69:                 control.MouseDoubleClick += ControlMouseDoubleClick;

  70:             else

  71:                 control.MouseDoubleClick -= ControlMouseDoubleClick;

  72:         }

  73:     }

  74:  

  75:     static void ControlMouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)

  76:     {

  77:         SetLastMouseEventArgs((DependencyObject)sender, e);

  78:     }

  79:  

  80:     #endregion

  81: }

then you can use that value as the CommandParameter… Something like this

   1: <ListBox ItemsSource="{Binding Data}" 

   2:         local:MouseEventArgsHandler.HandleMouseDoubleClick="True"

   3:         acb:CommandBehavior.Event="MouseDoubleClick" 

   4:         acb:CommandBehavior.Command="{Binding DoIt}"

   5:         acb:CommandBehavior.CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(local:MouseEventArgsHandler.LastMouseEventArgs)}" />

 

and here is what the command in the ViewModel looks like

   1: DoIt = new SimpleCommand

   2: {

   3:     ExecuteDelegate = x =>

   4:         {

   5:             //set the event as handled

   6:             ((MouseButtonEventArgs)x).Handled = true;

   7:             System.Diagnostics.Debug.WriteLine("Event handled");

   8:         }

   9: };

 

The down side of this is that you have to do an attached property for every different event you want to handle, yet at the same time this should be a rare case and if it is not then you should really re think what you are doing with MVVM.

 

Hope it helps 🙂

I created a demo project for anyone that wants to have a look.