Over a million developers have joined DZone.

How to Get the EventArgs as a CommandParameter Using the AttachedCommandBehavior

·

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:

public class MouseEventArgsHandler
{
#region LastMouseEventArgs

/// <summary>
/// LastMouseEventArgs Attached Dependency Property
/// </summary>
public static readonly DependencyProperty LastMouseEventArgsProperty =
DependencyProperty.RegisterAttached("LastMouseEventArgs", typeof(MouseButtonEventArgs), typeof(MouseEventArgsHandler),
new FrameworkPropertyMetadata((MouseButtonEventArgs)null));

/// <summary>
/// Gets the LastMouseEventArgs property. This dependency property
/// indicates ....
/// </summary>
public static MouseButtonEventArgs GetLastMouseEventArgs(DependencyObject d)
{
return (MouseButtonEventArgs)d.GetValue(LastMouseEventArgsProperty);
}

/// <summary>
/// Sets the LastMouseEventArgs property. This dependency property
/// indicates ....
/// </summary>
public static void SetLastMouseEventArgs(DependencyObject d, MouseButtonEventArgs value)
{
d.SetValue(LastMouseEventArgsProperty, value);
}

#endregion

#region HandleMouseDoubleClick

/// <summary>
/// HandleMouseDoubleClick Attached Dependency Property
/// </summary>
public static readonly DependencyProperty HandleMouseDoubleClickProperty =
DependencyProperty.RegisterAttached("HandleMouseDoubleClick", typeof(bool), typeof(MouseEventArgsHandler),
new FrameworkPropertyMetadata((bool)false,
new PropertyChangedCallback(OnHandleMouseDoubleClickChanged)));

/// <summary>
/// Gets the HandleMouseDoubleClick property. This dependency property
/// indicates ....
/// </summary>
public static bool GetHandleMouseDoubleClick(DependencyObject d)
{
return (bool)d.GetValue(HandleMouseDoubleClickProperty);
}

/// <summary>
/// Sets the HandleMouseDoubleClick property. This dependency property
/// indicates ....
/// </summary>
public static void SetHandleMouseDoubleClick(DependencyObject d, bool value)
{
d.SetValue(HandleMouseDoubleClickProperty, value);
}

/// <summary>
/// Handles changes to the HandleMouseDoubleClick property.
/// </summary>
private static void OnHandleMouseDoubleClickChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Control control = d as Control;
if (control != null)
{
if ((bool)e.NewValue)
control.MouseDoubleClick += ControlMouseDoubleClick;
else
control.MouseDoubleClick -= ControlMouseDoubleClick;
}
}

static void ControlMouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
SetLastMouseEventArgs((DependencyObject)sender, e);
}

#endregion
}

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

<ListBox ItemsSource="{Binding Data}" 
local:MouseEventArgsHandler.HandleMouseDoubleClick="True"
acb:CommandBehavior.Event="MouseDoubleClick"
acb:CommandBehavior.Command="{Binding DoIt}"
acb:CommandBehavior.CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(local:MouseEventArgsHandler.LastMouseEventArgs)}" />

and here is what the command in the ViewModel looks like:

DoIt = new SimpleCommand
{
ExecuteDelegate = x =>
{
//set the event as handled
((MouseButtonEventArgs)x).Handled = true;
System.Diagnostics.Debug.WriteLine("Event handled");
}
};

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.

 

Topics:

Published at DZone with permission of Marlon Grech. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}