Ho trovato un modo molto semplice e pulito per farlo con i trigger di evento Blend SDK. MVVM pulito, riutilizzabile e senza code-behind.
Probabilmente hai già qualcosa di simile:
<Style x:Key="MyListStyle" TargetType="{x:Type ListViewItem}">
Ora includi un ControlTemplate per ListViewItem come questo se non ne usi già uno:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<GridViewRowPresenter Content="{TemplateBinding Content}"
Columns="{TemplateBinding GridView.ColumnCollection}" />
</ControlTemplate>
</Setter.Value>
</Setter>
Il GridViewRowPresenter sarà la radice visiva di tutti gli elementi "all'interno" che costituiscono un elemento di riga di elenco. Ora potremmo inserire un trigger lì per cercare gli eventi indirizzati MouseDoubleClick e chiamare un comando tramite InvokeCommandAction come questo:
<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>
Se hai elementi visivi "sopra" il GridRowPresenter (probabilmente cominciando con una griglia) puoi anche mettere il Trigger lì.
Sfortunatamente gli eventi MouseDoubleClick non vengono generati da ogni elemento visuale (provengono da Controls, ma non da FrameworkElements per esempio). Una soluzione alternativa consiste nel derivare una classe da EventTrigger e cercare MouseButtonEventArgs con un ClickCount di 2. Questo filtra efficacemente tutti gli eventi non MouseButtonEvents e tutti i 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);
}
}
}
Ora possiamo scrivere questo ('h' è lo spazio dei nomi della classe helper sopra):
<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>