Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

How to Get the EventArgs as a CommandParameter Using the AttachedCommandBehavior

DZone's Guide to

How to Get the EventArgs as a CommandParameter Using the AttachedCommandBehavior

·
Free Resource

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 DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

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

X

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

{{ parent.tldr }}

{{ parent.urlSource.name }}