Double Click a ListBox item to open a browser
You can add a style to ListBox.ItemContainerStyle, and add an EventSetter there:
<ListBox> .... <ListBox.ItemContainerStyle> <Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}"> <EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/> </Style> </ListBox.ItemContainerStyle></ListBox>
ListBoxItem_MouseDoubleClick is a method in your code behind with the correct signature for MouseDoubleClick.
I wanted to solve this without needing to handle the listBoxItem double click event in the code-behind, and I didn't want to have to override the listBoxItem style (or define the style to override in the first place). I wanted to just fire a command when the listBox was doubleclicked.
I created an attached property like so (the code is very specific, but you can generalise it as required):
public class ControlItemDoubleClick : DependencyObject {public ControlItemDoubleClick(){}public static readonly DependencyProperty ItemsDoubleClickProperty = DependencyProperty.RegisterAttached("ItemsDoubleClick", typeof(bool), typeof(Binding));public static void SetItemsDoubleClick(ItemsControl element, bool value){ element.SetValue(ItemsDoubleClickProperty, value); if (value) { element.PreviewMouseDoubleClick += new MouseButtonEventHandler(element_PreviewMouseDoubleClick); }}static void element_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e){ ItemsControl control = sender as ItemsControl; foreach (InputBinding b in control.InputBindings) { if (!(b is MouseBinding)) { continue; } if (b.Gesture != null && b.Gesture is MouseGesture && ((MouseGesture)b.Gesture).MouseAction == MouseAction.LeftDoubleClick && b.Command.CanExecute(null)) { b.Command.Execute(null); e.Handled = true; } }}public static bool GetItemsDoubleClick(ItemsControl element){ return (bool)element.GetValue(ItemsDoubleClickProperty);}
}
I then declare my ListBox with the attached property and my target command:
<ListBox ItemsSource="{Binding SomeItems}" myStuff:ControlItemDoubleClick.ItemsDoubleClick="true"><ListBox.InputBindings> <MouseBinding MouseAction="LeftDoubleClick" Command="MyCommand"/></ListBox.InputBindings></ListBox>
Hope this helps.
I have updated AndrewS solution in order to solve the issue with firing executing the command if double click anywhere in the list box:
public class ControlDoubleClick : DependencyObject{ public static readonly DependencyProperty CommandProperty = DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(ControlDoubleClick), new PropertyMetadata(OnChangedCommand)); public static ICommand GetCommand(Control target) { return (ICommand)target.GetValue(CommandProperty); } public static void SetCommand(Control target, ICommand value) { target.SetValue(CommandProperty, value); } private static void OnChangedCommand(DependencyObject d, DependencyPropertyChangedEventArgs e) { Control control = d as Control; control.PreviewMouseDoubleClick += new MouseButtonEventHandler(Element_PreviewMouseDoubleClick); } private static void Element_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e) { Control control = sender as Control; ICommand command = GetCommand(control); if (command.CanExecute(null)) { command.Execute(null); e.Handled = true; } }}
And in the XAML the declaration for the ListBox is:
<ListBox ItemsSource="{Binding MyItemsSource, Mode=OneWay}"> <ListBox.ItemContainerStyle> <Style> <Setter Property="behaviours:ControlDoubleClick.Command" Value="{Binding DataContext.MyCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"/> </Style> </ListBox.ItemContainerStyle></ListBox>