Why is the TreeViewItem's MouseDoubleClick event being raised multiple times per double click?

Viewed 13895

XAML

<TreeView Name="GroupView" ItemsSource="{Binding Documents}">
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <EventSetter Event="MouseDoubleClick" Handler="OnTreeNodeDoubleClick"/>
                </Style>
            </TreeView.ItemContainerStyle>
            ....
</TreeView>

Code-Behind

private void OnTreeNodeDoubleClick(object sender, MouseButtonEventArgs mouseEvtArgs)
       {
           Console.WriteLine("{3} MouseDoubleClick Clicks={0} ChangedButton={1} Source={2} Handled={4} ButtonState={5}",
               mouseEvtArgs.ClickCount, mouseEvtArgs.ChangedButton, mouseEvtArgs.OriginalSource,
               mouseEvtArgs.Timestamp, mouseEvtArgs.Handled, mouseEvtArgs.ButtonState);
       }

I find that for one double click, the event handler is called multiple times. I'm trying to open up a document in tab on a double-click on the corresponding tree node; so I'd need to filter out the extra calls.

23479156 MouseDoubleClick Clicks=1 ChangedButton=Left Source=System.Windows.Controls.TextBlock Handled=False ButtonState=Pressed
23479156 MouseDoubleClick Clicks=1 ChangedButton=Left Source=System.Windows.Controls.TextBlock Handled=False ButtonState=Pressed

In my slightly-complicated app, it is being raised 4 times per double-click. On a simple repro-app, it is being raised 2 times per double click. Also all the event argument parameters are the same too, so I can't distinguish the last one of a set.

Any ideas why this is the way it is?

9 Answers

I have a little bit more elegant solution than checking for selection or creating flags:

A helper method:

public static object GetParent(this DependencyObject obj, Type expectedType) {

    var parent = VisualTreeHelper.GetParent(obj);
    while (parent != null && parent.GetType() != expectedType)
        parent = VisualTreeHelper.GetParent(parent);

    return parent;
}

And then your handler:

public void HandleDoubleClick(object sender, MouseButtonEventArgs e)
{
    if (e.OriginalSource is DependencyObject)
        if (sender == (e.OriginalSource as DependencyObject).GetParent(typeof(TreeViewItem))) 
    {
        // sender is the node, which was directly doubleclicked
    }
}

The most likely reason is that the doubleclick handler is installed multiple times, so each instance of the handler is being called once for each click.

Related