【问题标题】:Find what event handler has been assigned to an event on an object WPF [duplicate]查找已将哪个事件处理程序分配给对象 WPF 上的事件 [重复]
【发布时间】:2012-11-28 19:50:40
【问题描述】:

可能重复:
Has an event handler already been added?

首先,我知道有许多类似的问题,但我无法根据自己的情况调整它们。

我希望能够找出为对象上的特定事件分配了哪个事件处理程序。因此,在树视图项上,我将为扩展事件分配一个处理程序。然后,我希望以后能够将分配的事件处理程序拉出并将其分配给另一个 treeviewitems 扩展事件,以便它们都在扩展事件上调用相同的处理程序。

这可能吗?

这就是我想要做的事情......

private void duplicateHandler( TreeViewItem existingItem )
{
    TreeViewItem tvi = new GX3TreeViewItem();

    tvi.AddHandler(TreeViewItem.ExpandedEvent, existingItem.ExpandedEventHandler);
}

【问题讨论】:

  • 我已经看过了,但是有很多关于它的问题。该方法将进入哪个类?扩展的 treeviewitem 类?如果是这样,我如何获得分配的扩展处理程序?

标签: c# wpf event-handling


【解决方案1】:
  1. 创建一个新的 WPF 应用程序
  2. 在主窗口中放置一个名为“tree1”的树视图
  3. 复制粘贴下面的代码以查看实际效果

基本上,您需要继承 TreeViewItem 并构建一种机制来跟踪哪些处理程序被添加到哪个节点:很遗憾,event 没有关于已注册处理程序的信息供您检索。

您还需要完全依赖新的继承来构建节点,以使事情正常工作。这意味着,您不能再引用TreeViewItem,而必须引用TreeNode(这是我为自定义类选择的名称,请随意更改)。

Promised 代码如下,它所做的是将“rootNode”节点添加到树中,在扩展时会创建一个兄弟节点,该节点会将相同的处理程序带入自身(因此它也会创建一个兄弟节点扩展等)。

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            TreeNode root = new TreeNode();
            root.Header = "root";

            tree1.Items.Clear();

            // add node to tree before adding handlers, or you'll get
            // a StackOverflowException
            tree1.Items.Add(root);

            root.AddHandler(TreeNode.ExpandedEvent, new RoutedEventHandler(expandedHandler));

        }

        private void expandedHandler(object sender, RoutedEventArgs e) { newNodeCopyExpandedHandlers(sender as TreeNode); }

        private void newNodeCopyExpandedHandlers(TreeNode node)
        {
            TreeNode newNode = new TreeNode();
            newNode.Header = "nuovo!";

            // add node to tree before adding handlers, or you'll get
            // a StackOverflowException
            tree1.Items.Add(newNode);

            foreach (Delegate d in newNode.GetHandlers(node, TreeNode.ExpandedEvent))
                newNode.AddHandler(TreeNode.ExpandedEvent, d);
        }
    }

    public class TreeNode : TreeViewItem
    {
        private Dictionary<RoutedEvent, List<Delegate>> handlersList = new Dictionary<RoutedEvent, List<Delegate>>();

        public new void AddHandler(RoutedEvent e, Delegate d)
        {
            if (!handlersList.ContainsKey(e)) handlersList.Add(e, new List<Delegate>());
            handlersList[e].Add(d);

            base.AddHandler(e, d);
        }
        public new void RemoveHandler(RoutedEvent e, Delegate d)
        {
            if (!handlersList.ContainsKey(e)) handlersList.Add(e, new List<Delegate>());
            if (handlersList[e].Contains(d)) handlersList[e].Remove(d);

            base.RemoveHandler(e, d);
        }

        public List<Delegate> GetHandlers(TreeNode n, RoutedEvent e)
        {
            if (n.handlersList.ContainsKey(e)) return n.handlersList[e];
            else return null;
        }
    }
}

【讨论】:

  • 非常感谢 :)
【解决方案2】:

是的,当然可以,您可以在代码中导航,直到找到事件分配:

event +=  myEventHandler

然后您可以使用相同的方法myEventHandler 订阅其他树上的事件。这是问题还是我误解了这个问题?

【讨论】:

  • 你有点误会了,我需要能够在运行时检查treeviewitem并获得对其扩展事件处理程序的引用。
  • 引用的是事件本身,请贴一些代码以便更好理解
  • 更新问题。如果您需要更多信息,请告诉我:)
  • 奇怪,TreeNodes没有事件..你有没有创建一个自定义的带有事件的树节点?
  • 我有但没有添加任何事件。问题是关于 WPF 而不是 winforms。不确定winforms树节点是否有事件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多