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
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.




