I think you should use attached behavior because
- MVVM ♥ Attached Behavior
- It is reusable: once you create the attached behavior and the commands for a double click, you can attach it to any other control type (so you could use the same code to double click an image etc)
- Abstracts the dirty implementation so the xaml and the view model are both much more legible
- The way they work is awesome, and I love using clever code.
Heres what you do:

Create the ListViewItemDoubleClickCommandBehavior
As you can see from the above diagram, this CommandBehavior
class links the command to the control.
In the case above its for a buttonbase, but we are gonna make a ListViewItem one
You are going to need prism for this one, as the CommandBehaviorBase, which this inherits from, is part of that library. You can get it all here (but for this example you only need to Prism.Commands dll)
Naming convention says you should name this CommandBehavior in the format
[X][Y]CommandBehavior
X - The name of the control to which we are binding the command (in this case ListViewItem)
Y - The Action the user performs that will cause the command to happen (in this case DoubleClick)
Heres the code:
public class ListViewItemDoubleClickCommandBehaviour : CommandBehaviorBase<ListViewItem>
{
public ListViewItemDoubleClickCommandBehaviour(ListViewItem controlToWhomWeBind)
: base(controlToWhomWeBind)
{
controlToWhomWeBind.MouseDoubleClick += OnDoubleClick;
}
private void OnDoubleClick(object sender, System.Windows.RoutedEventArgs e)
{
ExecuteCommand();
}
}
Create a DoubleClick Static class
This class will house all the double click command stuff.
Its called doubleclick because it represents the actual act of double clicking. Each other kind of action (say you wanted a command for button down in a textbox) will have its own class with its command, commandparameter and behavior can we can then access.
The commands are dependency properties of type ICommand
(I'm assuming you have implemented this interface, because you kinda need it for MVVM)
One dependency property for the command itself and one for the parameters the command needs (in this case you will probably use the selected item as a parameter)
This class has an instance of the ListViewItemDoubleClickCommandBehavior as a dependency property. This is how the link is created between the command you bind to your control and the double click event in the ListViewItemDoubleClickCommandBehaviour. We use some of the CommandBehaviorBase's magic methods to create the behavior and pass it the command to execute.
The OnSetCommand and OnSetCommandParameter callbacks are used to wire the Behavior to the command. Every time the command changes, we set that as the new command for the behavior to run. These callbacks are registered to the DependencyProperties in the PropertyMetadata part of the constructor. These get fired whenever the dependency property is changed.
Here is that class's code:
public static class DoubleClick
{
public static readonly DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached(
"Command",
typeof(ICommand),
typeof(DoubleClick),
new PropertyMetadata(OnSetCommandCallback));
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.RegisterAttached(
"CommandParameter",
typeof(object),
typeof(DoubleClick),
new PropertyMetadata(OnSetCommandParameterCallback));
private static readonly DependencyProperty DoubleClickCommandBehaviorProperty =
DependencyProperty.RegisterAttached(
"DoubleClickCommandBehavior",
typeof(ListViewItemDoubleClickCommandBehaviour),
typeof(DoubleClick),
null);
public static void SetCommand(ListViewItem controlToWhomWeBind, ICommand value)
{
controlToWhomWeBind.SetValue(CommandProperty, value);
}
public static ICommand GetCommand(ListViewItem controlToWhomWeBind)
{
return (ICommand)controlToWhomWeBind.GetValue(CommandProperty);
}
public static void SetCommandParameter(ListViewItem controlToWhomWeBind, ICommand value)
{
controlToWhomWeBind.SetValue(CommandParameterProperty, value);
}
public static ICommand GetCommandParameter(ListViewItem controlToWhomWeBind)
{
return (ICommand)controlToWhomWeBind.GetValue(CommandParameterProperty);
}
private static void OnSetCommandCallback(DependencyObject dependencyObject,
DependencyPropertyChangedEventArgs e)
{
ListViewItem controlToWhomWeBind= dependencyObject as ListViewItem;
if (controlToWhomWeBind!= null)
{
ListViewItemDoubleClickCommandBehaviour behavior = GetOrCreateBehavior(controlToWhomWeBind);
behavior.Command = e.NewValue as ICommand;
}
}
private static void OnSetCommandParameterCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
ListViewItem controlToWhomWeBind= dependencyObject as ListViewItem;
if (controlToWhomWeBind!= null)
{
ListViewItemDoubleClickCommandBehaviour behavior = GetOrCreateBehavior(controlToWhomWeBind);
behavior.CommandParameter = e.NewValue;
}
}
private static ListViewItemDoubleClickCommandBehaviour GetOrCreateBehavior(
ListViewItem controlToWhomWeBind)
{
ListViewItemDoubleClickCommandBehaviour behavior =
controlToWhomWeBind.GetValue(DoubleClickCommandBehaviorProperty) as
ListViewItemDoubleClickCommandBehaviour;
if (behavior == null)
{
behavior = new ListViewItemDoubleClickCommandBehaviour (controlToWhomWeBind);
controlToWhomWeBind.SetValue(DoubleClickCommandBehaviorProperty, behavior);
}
return behavior;
}
}
Note:
I know this looks like alot of complex code, but its a simple pattern once you use it often enough, and it abstracts all the complexity out of your view model, so that the binding of the command to the control looks remarkably simple.
Create the command in your viewmodel and bind to it in the xaml
Now that the grunt work is over, we do the easy part.
Creating the Command
I assume that you are familiar with commands, you create the command as you always do:
public ICommand DisplaySelectedItemCmd { get; protected set; }
//This method goes in your constructor
private void InitializeCommands()
{
//Initializes the command
this.DisplaySelectedItemCmd = new RelayCommand(
(param) =>
{
this.DisplaySelectedItem((object)param);
},
(param) => { return this.CanDisplaySelectedItem; }
);
}
//The parameter should be your listview's selected item. I have no idea what type it is so I made it an object
public void DisplaySelectedPolicy(object selectedListViewItem)
{
//Code to perform when item is double clicked
}
private bool CanDisplaySelectedPolicy
{
get
{
return true; //Change this bool if you have any reason to disable the double clicking, as this bool basically is linked to the double click command firing.
}
}
Creating the binding in xaml
And now for the beautiful part.
First add the xml namespace:
xmlns:commands="clr-namespace:CommandHandling"
and then bind on your ListViewItem
<Style TargetType="{x:Type ListViewItem}" x:Key="{x:Type ListViewItem}" >
<Setter Property="commands:DoubleClick.Command" Value="{Binding Path=bleh}"/>
</Style>
and done.
If this doesn't work let me know. (And anyone reading this in the future, you can ask me for help if you like)
u_u