I have a WPF TreeView and want to listen for doubleclicks on all TreeViewItems that have no Children. My TreeView looks like this:
The content of the TreeView is generated like this:
TreeViewItem tvi = new TreeViewItem();
tvi.Header = groupModel.Name;
treeView.Items.Add(tvi);
foreach(Model m in models) {
TreeViewItem t = new TreeViewItem();
t.Header = model.Name;
tvi.Items.Add(t);
}
In my XAML File I have defined a EventSetter that should trigger when a TreeViewItem is clicked:
<TreeView x:Name="treeView" BorderThickness="0">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<EventSetter Event="MouseDoubleClick" Handler="OnTreeItemDoubleClick"/>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
In my Code Behind I define the Handler:
public void OnTreeItemDoubleClick(object sender, EventArgs args)
{
TreeViewItem tvi = (TreeViewItem)sender;
}
When I doubleclick on any TreeViewItem, the Handler is triggered, but everytime the sender is TreeViewItem "Level 1". I want to get the actual TreeViewItem that was clicked. How do I accomplish this?
EDIT (workaround for now)
I have been thinking way to complicated. I just attached a Handler to the MouseDoubleClick Event when the TreeViewItem is generated:
t.MouseDoubleClick += OnTreeItemDoubleClick;
I am still interested in a solution to the described problem and want to know why the routed event is not triggered by the most nested child.
I noticed that if you are not using
HierarchicalDataTemplate
and databinding, and instead add items in code, then theEventSetter
sets the event only for the first level of the tree. I wonder why that happens (I haven't found an answer to his question myself yet).The workaround is to just subscribe to the event in code (as you are adding the items manually anyway):
Beware you are using
EventArgs
in your handler, where it should beMouseButtonEventArgs
.Also, since every
TreeViewItem
is in the visual tree of its parent, the event will bubble down, so if you clicked the tree leaf withMouseDoubleClick
assigned and it has 2 parents, then the event will be called 3 times. To only handle it once you can check itsOriginalSource
: