问题描述
我有一个 WPF TreeView,想监听所有没有子项的 TreeViewItems 的双击.我的 TreeView 看起来像这样:
I have a WPF TreeView and want to listen for doubleclicks on all TreeViewItems that have no Children. My TreeView looks like this:
TreeView 的内容是这样生成的:
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);
}
在我的 XAML 文件中,我定义了一个应在单击 TreeViewItem 时触发的 EventSetter:
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;
}
当我双击任何 TreeViewItem 时,会触发 Handler,但每次发送者都是 TreeViewItemLevel 1".我想获得被点击的实际 TreeViewItem.我该如何实现?
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?
编辑(暂时的解决方法)
我一直在想办法复杂化.我只是在生成 TreeViewItem 时将处理程序附加到 MouseDoubleClick 事件:
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.
推荐答案
我注意到,如果您不使用 HierarchicalDataTemplate
和数据绑定,而是在代码中添加项目,那么 EventSetter
只为树的第一层设置事件.我想知道为什么会这样(我自己还没有找到他问题的答案).
I noticed that if you are not using HierarchicalDataTemplate
and databinding, and instead add items in code, then the EventSetter
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):
TreeViewItem tt = new TreeViewItem();
tt.Header = "some item";
tt.MouseDoubleClick += new MouseButtonEventHandler(OnTreeItemDoubleClick);
注意您在处理程序中使用了 EventArgs
,它应该是 MouseButtonEventArgs
.
Beware you are using EventArgs
in your handler, where it should be MouseButtonEventArgs
.
此外,由于每个 TreeViewItem
都在其父级的可视化树中,该事件将向下冒泡,因此如果您单击分配了 MouseDoubleClick
的树叶并且它有2 个父母,那么该事件将被调用 3 次.只处理一次你可以检查它的OriginalSource
:
Also, since every TreeViewItem
is in the visual tree of its parent, the event will bubble down, so if you clicked the tree leaf with MouseDoubleClick
assigned and it has 2 parents, then the event will be called 3 times. To only handle it once you can check its OriginalSource
:
public void OnTreeItemDoubleClick(object sender, MouseButtonEventArgs e)
{
TreeViewItem clickedItem = TryGetClickedItem(treeView, e);
if (clickedItem == null || clickedItem!=sender)
return;
//e.Handled = true; // if you want to to cancel expanded/collapsed toggle
Console.WriteLine(clickedItem.Header);
}
TreeViewItem TryGetClickedItem(TreeView treeView, MouseButtonEventArgs e)
{
var hit = e.OriginalSource as DependencyObject;
while (hit != null && !(hit is TreeViewItem))
hit = VisualTreeHelper.GetParent(hit);
return hit as TreeViewItem;
}
这篇关于用于双击 TreeView 中最后一个子项的 C# WPF 事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!