Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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?

like image 682
Gishu Avatar asked Feb 17 '10 11:02

Gishu


2 Answers

I know this is an old question, but as I came across it in my searches for the solution, here are my findings for any future visitors!

TreeViewItems are recursively contained within each other. TreeViewItem is a HeaderedContentControl (see msdn), with the child nodes as the Content. So, each TreeViewItem's bounds include all of its child items. This can be verified using the excellent WPF Inspector by selecting a TreeViewItem in the visual tree, which will highlights the bounds of the TreeViewItem.

In the OP's example, the MouseDoubleClick event is registered on each TreeViewItem using the style. Therefore, the event will be raised for the TreeViewItems that you double-clicked on - and each of its parent items - separately. This can be verified in your debugger by putting a breakpoint in your double-click event handler and putting a watch on the event args' Source property - you will notice that it changes each time the event handler is called. Incidentally, as can be expected, the OriginalSource of the event stays the same.

To counter this unexpected behaviour, checking whether the source TreeViewItem is selected, as suggested by Pablo in his answer, has worked the best for me.

like image 87
Riaan Avatar answered Dec 07 '22 23:12

Riaan


When a TreeViewItem is double clicked, that item is selected as part of the control behavior. Depending on the particular scenario it could be possible to say:

... TreeViewItem tviSender = sender as TreeViewItem;  if (tviSender.IsSelected)     DoAction(); ... 
like image 30
Pablo Avatar answered Dec 08 '22 01:12

Pablo