J'ai trouvé un moyen très simple et propre de le faire avec les déclencheurs d'événements du SDK Blend. Clean MVVM, réutilisable et sans code-behind.
Vous avez probablement déjà quelque chose comme ça:
<Style x:Key="MyListStyle" TargetType="{x:Type ListViewItem}">
Incluez maintenant un ControlTemplate pour le ListViewItem comme celui-ci si vous n'en utilisez pas déjà un:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<GridViewRowPresenter Content="{TemplateBinding Content}"
Columns="{TemplateBinding GridView.ColumnCollection}" />
</ControlTemplate>
</Setter.Value>
</Setter>
Le GridViewRowPresenter sera la racine visuelle de tous les éléments "à l'intérieur" constituant un élément de ligne de liste. Nous pourrions maintenant y insérer un déclencheur pour rechercher les événements routés MouseDoubleClick et appeler une commande via InvokeCommandAction comme ceci:
<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 vous avez des éléments visuels "au-dessus" du GridRowPresenter (probablement en commençant par une grille), vous pouvez également y placer le Trigger.
Malheureusement, les événements MouseDoubleClick ne sont pas générés à partir de chaque élément visuel (ils proviennent de Controls, mais pas de FrameworkElements par exemple). Une solution de contournement consiste à dériver une classe de EventTrigger et à rechercher MouseButtonEventArgs avec un ClickCount de 2. Cela filtre efficacement tous les non-MouseButtonEvents et tous les MoseButtonEvents avec 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);
}
}
}
Maintenant, nous pouvons écrire ceci ('h' est l'espace de noms de la classe d'assistance ci-dessus):
<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>