He encontrado una forma muy fácil y limpia de hacer esto con los activadores de eventos de Blend SDK. MVVM limpio, reutilizable y sin código subyacente.
Probablemente ya tengas algo como esto:
<Style x:Key="MyListStyle" TargetType="{x:Type ListViewItem}">
Ahora incluya un ControlTemplate para ListViewItem como este si aún no usa uno:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<GridViewRowPresenter Content="{TemplateBinding Content}"
Columns="{TemplateBinding GridView.ColumnCollection}" />
</ControlTemplate>
</Setter.Value>
</Setter>
GridViewRowPresenter será la raíz visual de todos los elementos "dentro" que componen un elemento de fila de lista. Ahora podríamos insertar un disparador allí para buscar eventos enrutados MouseDoubleClick y llamar a un comando a través de InvokeCommandAction como este:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<GridViewRowPresenter Content="{TemplateBinding Content}"
Columns="{TemplateBinding GridView.ColumnCollection}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding DoubleClickCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</GridViewRowPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
Si tiene elementos visuales "encima" del GridRowPresenter (probablemente comenzando con una cuadrícula), también puede colocar el Trigger allí.
Desafortunadamente, los eventos MouseDoubleClick no se generan a partir de todos los elementos visuales (son de Controls, pero no de FrameworkElements, por ejemplo). Una solución alternativa es derivar una clase de EventTrigger y buscar MouseButtonEventArgs con un ClickCount de 2. Esto filtra eficazmente todos los eventos que no son MouseButtonEvents y todos los MoseButtonEvents con un ClickCount! = 2.
class DoubleClickEventTrigger : EventTrigger
{
protected override void OnEvent(EventArgs eventArgs)
{
var e = eventArgs as MouseButtonEventArgs;
if (e == null)
{
return;
}
if (e.ClickCount == 2)
{
base.OnEvent(eventArgs);
}
}
}
Ahora podemos escribir esto ('h' es el espacio de nombres de la clase auxiliar anterior):
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<GridViewRowPresenter Content="{TemplateBinding Content}"
Columns="{TemplateBinding GridView.ColumnCollection}">
<i:Interaction.Triggers>
<h:DoubleClickEventTrigger EventName="MouseDown">
<i:InvokeCommandAction Command="{Binding DoubleClickCommand}" />
</h:DoubleClickEventTrigger>
</i:Interaction.Triggers>
</GridViewRowPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>