WPF ListView ScrollViewer Double-Click Event

double-clicklistviewscrollviewerwpf

Doing the below will reproduce my problem:

  • New WPF Project
  • Add ListView
  • Name the listview: x:Name="lvList"
  • Add enough ListViewItems to the ListView to fill the list completely so a vertical scroll-bar appears during run-time.
  • Put this code in the lvList.MouseDoubleClick event

Debug.Print("Double-Click happened")

  • Run the application
  • Double-click on the LargeChange area of the scroll-bar (Not the scroll "bar" itself)
  • Notice the Immediate window printing the double-click happened message for the ListView

How do I change this behavior so MouseDoubleClick only happens when the mouse is "over" the ListViewItems and not when continually clicking the ScrollViewer to scroll down/up in the list?

Best Answer

You can't change the behaviour, because the MouseDoubleClick handler is attached to the ListView control, so it has to occur whenever the ListView is clicked -- anywhere. What you can do it detect which element of the ListView first detected the double-click, and figure out from there whether it was a ListViewItem or not. Here's a simple example (omitting error checking):

private void lv_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
  DependencyObject src = (DependencyObject)(e.OriginalSource);
  while (!(src is Control))
    src = VisualTreeHelper.GetParent(src);
  Debug.WriteLine("*** Double clicked on a " + src.GetType().Name);
}

Note the use of e.OriginalSource to find the actual element that was double-clicked. This will typically be something really low level like a Rectangle or TextBlock, so we use VisualTreeHelper to walk up to the containing control. In my trivial example, I've assumed that the first Control we hit will be the ListViewItem, which may not be the case if you're dealing with CellTemplates that contain e.g. text boxes or check boxes. But you can easily refine the test to look only for ListViewItems -- but in that case don't forget to handle the case there the click is outside any ListViewItem and the search eventually hits the ListView itself.