简体   繁体   English

在TreeView中离开节点时发生的事件

[英]Event when leaving a node in TreeView

I have overridden the TreeView events BeforeSelect and AfterSelect . 我已经重写了TreeView事件BeforeSelectAfterSelect Both get called when clicking on a node in the tree. 单击树中的节点时,两者都会被调用。 You can see in the code below that I'm outputting the name of the tree node in each method. 您可以在下面的代码中看到,我正在每种方法中输出树节点的名称。 Suppose the tree looks like so: 假设树看起来像这样:

UpperNode1 上层节点1
--LowerNode1a --LowerNode1a
--LowerNode1b --LowerNode1b
UpperNode2 上层节点2
--LowerNode2a --LowerNode2a
--LowerNode2b --LowerNode2b

and suppose LowerNode1a is currently selected. 并假设当前选择了LowerNode1a。 When clicking then on LowerNode1b, eventArgs.Node.Name is "LowerNode1b" in both methods. 单击然后单击LowerNode1b时,两种方法中的eventArgs.Node.Name均为“ LowerNode1b”。 I was hoping that in the BeforeSelect , that eventArgs.Node.Name would be "LowerNode1a" because I wanted to do some work on that node upon leaving it. 我希望在BeforeSelect ,该eventArgs.Node.Name将为“ LowerNode1a”,因为我想在离开该节点时对该节点做一些工作。 How can I do this? 我怎样才能做到这一点?

private void trv_BeforeSelect(object sender, TreeViewCancelEventArgs eventArgs)
{
    System.Diagnostics.Trace.WriteLine("trvApproval_BeforeSelect(): eventArgs.Node.Name: " + eventArgs.Node.Name);
}

private void trv_AfterSelect(object sender, TreeViewEventArgs eventArgs)
{
    System.Diagnostics.Trace.WriteLine("trvApproval_AfterSelect(): eventArgs.Node.Name: " + eventArgs.Node.Name);
}

Edit: 编辑:
The sender parameter is a TreeView object. sender参数是TreeView对象。 Unfortunately SelectedNode is null. 不幸的是, SelectedNode为空。 Strangely, there is a member prevHoveredNode (which has a valid value even) but not a prevSelectedNode . 奇怪的是,有一个成员prevHoveredNode (甚至具有有效值),但没有prevSelectedNode

You can just use the SelectedNode property of the TreeView inside the BeforeSelect event. 您可以只在BeforeSelect事件中使用TreeView的SelectedNode属性。

treeView1.BeforeSelect += (s, e) =>
{
    var selected = treeView1.SelectedNode;
    var next = e.Node;
};

if UpperNode1 was selected and you click LowerNode1a then UpperNode1 is selected and LowerNode1a is next 如果UpperNode1被选中,并单击LowerNode1a然后UpperNode1的selected和LowerNode1a是next

You are using the incorrect events. 您正在使用不正确的事件。 Those events are meant to do things if a TreeNode is selected. 如果选择了TreeNode则这些事件将用于执行操作。 With BeforeSelect you can indicate that you don't allow this selection, with AfterSelect you can decide what to do with the selected TreeNode once if has been selected. 使用BeforeSelect可以指示您不允许此选择,使用AfterSelect可以确定一旦选择了对所选TreeNode

However, you don't want to do anything with the selected TreeNode , you want to do something with the item that this selected TreeNode stands for. 但是,您不希望对选定的TreeNode做任何事情,而是想要对该选定的TreeNode代表的项目做任何事情。 In fact, if it wasn't a TreeView, but another class in which you could select items, you'd want your code still to work. 实际上,如果它不是TreeView,而是另一个可以在其中选择项目的类,则希望代码仍能正常工作。

Therefor, you need an event that is called when an Item is selected. 因此,您需要选择一个项目时调用的事件。 Microsoft forgot that, and you'll see that they added it later in System.Windows.Control.SelectedItemChanged See also why isn't there a SelectedNodeChange for TreeView? Microsoft忘记了这一点,您将看到他们稍后在System.Windows.Control.SelectedItemChanged中添加了它。另请参见为什么没有TreeView的SelectedNodeChange?

Alas this doesn't help you. this,这对您没有帮助。 The neat thing would be to derive a class from TreeView, so you could use for other purposes in future. 整洁的事情是从TreeView派生一个类,因此您将来可以将其用于其他目的。 If you are sure you will only do this once, don't derive, do it in your destination class 如果您确定只执行一次,则不要派生,请在目标类中执行

class MyTreeView : System.Windows.Forms.TreeView
{
    public TreeNode SelectedNode {get; set;}

    protected override void OnAfterSelect(TreeViewEventArgs e)
    {
         // raise event that previous node is DeSelected
         if (this.SelectedNode != null)
         {
             this.OnNodeDeselected(e.Action);
         }
         if (e.Node != null && e.Node.IsSelected)
         {
             this.OnNodeSelected(e);
         }
    }

    protected virtual void OnNodeDeselected(TreeViewAction action)
    {
         TreeViewEventArgs eventArgs = new TreeViewEventArgs(this.SelectedNode, action);
         // TODO: raise deselect event
         this.SelectedNode = null; // nothing selected anymore
    }

    protected virtual void OnNodeSelected(TreeViewEventArgs e)
    {
        // TODO: raise event to indicate a node has been selected
        this.SelectedNode = e.Node
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM