本文介绍了用于双击 TreeView 中最后一个子项的 C# WPF 事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 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 事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-12 14:36