How to Get the EventArgs as a CommandParameter Using the AttachedCommandBehavior
Join the DZone community and get the full member experience.
Join For FreeI 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.
Published at DZone with permission of Marlon Grech. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Effective Java Collection Framework: Best Practices and Tips
-
Microservices With Apache Camel and Quarkus
-
Writing a Vector Database in a Week in Rust
-
How To Approach Java, Databases, and SQL [Video]
Comments