当前位置: 首页 > 知识库问答 >
问题:

双击树视图中最后一个子项的C#WPF事件

南门祯
2023-03-14

我有一个WPF TreeView,希望在所有没有子项的TreeView项目上侦听双击。我的树视图如下所示:

树状视图的内容是这样生成的:

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文件中,我定义了一个EventSetter,单击TreeViewItem时应该触发它:

<TreeView x:Name="treeView" BorderThickness="0">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <EventSetter Event="MouseDoubleClick" Handler="OnTreeItemDoubleClick"/>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

在我的代码隐藏中,我定义了处理程序:

public void OnTreeItemDoubleClick(object sender, EventArgs args)
{
    TreeViewItem tvi = (TreeViewItem)sender;
}

当我双击任何TreeViewItem时,处理程序被触发,但每次发送者都是TreeViewItem“级别1”。我想得到点击的实际TreeViewItem。我该如何实现这一点?

编辑(目前的解决方法)

我一直在想复杂的方法。我只是附加了一个处理程序到鼠标双击事件时,TreeViewItem生成:

t.MouseDoubleClick += OnTreeItemDoubleClick;

我仍然对所描述的问题的解决方案感兴趣,并且想知道为什么路由事件不是由嵌套最多的子级触发的。

共有1个答案

芮叶秋
2023-03-14

我注意到,如果您不使用层次数据模板和数据库绑定,而是在代码中添加项目,那么EventSetter仅为树的第一级设置事件。我想知道为什么会这样(我自己还没有找到他问题的答案)。

解决方法是在代码中订阅事件(因为您无论如何都要手动添加项目):

TreeViewItem tt = new TreeViewItem();
tt.Header = "some item";
tt.MouseDoubleClick += new MouseButtonEventHandler(OnTreeItemDoubleClick);

请注意,您在处理程序中使用的是EventArgs,应该是MouseButtonEventArgs

此外,由于每个TreeViewItem都位于其父级的可视树中,因此事件将冒泡,因此如果您在指定了MouseDoubleClick的情况下单击树叶,并且它有两个父级,则事件将被调用3次。要仅处理它一次,请检查它的原始源文件

    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;
    }
 类似资料:
  • 新加入WPF的我正尝试使用TreeView,它提供的灵活性给我留下了难以置信的印象。 到目前为止,我的每个treeview项目都实现了一个扩展器,这是显示每个项目更详细信息并让标题仅显示摘要的好方法。但是,这不适合叶项目,并且浪费了屏幕空间——我的treeview中的每个叶项目(其中有许多)显示的数据量相对较小。 我想要为叶项目实现的是水平包装,而不是垂直列表。设想显示一个网格或(stackpan

  • 我有一个树状视图,其中有可选择的项,以及可能触发某些代码操作的子项。单击子项时,应执行操作,但父项必须保留/成为选定项。 我面临的问题是项目没有被正确取消选择,导致在树视图中选择多个项目。 以下是treeview的xaml: clsBindingDebugger除了调试打印转换的值并传递转换和转换回值之外什么也不做。 接下来是TreeviewItem类的略为缩短的版本 最后我触发事件MyTreev

  • 我正在学习WPF,我想我缺少一些用户控件。我将尝试用例子来演示。基本上,假设我有一个treeview,我想将标签文本绑定到treeview selectedItem。这似乎很简单: 现在,为了使事情复杂化,我将在混合中添加一个用户控件。用户控件基本上是网格中的TreeView: 其目的是用usercontrol替换上面使用的vanilla treeview,并根据所选内容更改标签内容。所以,我试着

  • 我正在做一个双链表的实现。我希望链表有一定的长度限制。当列表变长时,删除最后一个节点。我这里有些问题。我想定义尾巴,这样我就不必寻找终点。下面是我正在研究的实现,它将允许长度为4,然后开始删除最后一个节点。 它似乎在删除最后一个节点,但之后会打印一些奇怪的符号。我猜这是我如何释放的问题,但我想不出来。注意:此代码中的一些代码取自https://gist.github.com/mycodeschoo

  • 有没有办法用java捕获双击鼠标事件后的图像?我只能在鼠标释放双击事件时捕获图像。但捕获图像不是双击事件后的图像。

  • 我有一个绑定到MVVM可观察集合的TreeView。我的项目模板由图像和文本块组成,如以下代码所示: 当然,发生这种情况是因为堆栈面板现在位于选择区域上方。 有什么解决办法吗?