3

I'd like to programmatically emulate a click on a node in a TreeView control. There's no clickable method as far I can see (something corresponding to other controls) and I guess that I need to go for the currently selected node.

So I've tried the following:

christmasTreeView.SelectedNode. ???

However, intellisense gave me no hint on what to call in order to fire a clickety-click on the node. How can it be done?

Community
  • 1
  • 1
Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
  • You need to set `SelectedNode` to the node you want to emulate click for. so it should be something like this `christmasTreeView.SelectedNode = nodeyouwanttoselect`. – Michael Dec 11 '14 at 10:27
  • 1
    Why? What are you trying to achieve? There is probably a better way... – t3chb0t Dec 11 '14 at 10:28

3 Answers3

4

You can do something like:

// find the node you want to select and make it the SelectedNode
christmasTreeView.SelectedNode = christmasTreeView.Nodes[1]; // <-- the index you need
// Now trigger a select
christmasTreeView.Select();
// or
//christmasTreeView.Focus();

This will fire:

private void christmasTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
   // awesome
}

Possible approach (not very smooth, though).

TreeNode preSelected = ChristmasTreeView.SelectedNode;
ChristmasTreeView.SelectedNode = null;
ChristmasTreeView.SelectedNode = preSelected;
ChristmasTreeView.Select();
Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
Dimitar Dimitrov
  • 14,868
  • 8
  • 51
  • 79
  • Sorry for being unclear. I need to emulate a **click on the node*. Toggling is equivalent to folding/unfolding a parent node. I need to emulate a click on the leaf (no folding/unfolding). I need to fire the method with a signature *private void treeView1_AfterSelect(Object sender, TreeViewEventArgs eventArgs)*. – Konrad Viltersten Dec 11 '14 at 11:27
  • @KonradViltersten I've edited my answer, give it a shot. – Dimitar Dimitrov Dec 11 '14 at 12:03
  • Hmmm... Not sure if we miss each other here. On the *SelectedNode*, there seems to be no such methods. Those methods exist in the *christmasTreeView*, though. However, invoking them doesn't seem to fire the event as the method *private void ChristmasTreeView_AfterSelect(Object sender, TreeViewEventArgs eventArgs)* doesn't get stopped on the breakpoint. It does hit the breakie if I physically click on a leaf, though... – Konrad Viltersten Dec 11 '14 at 12:05
  • @KonradViltersten I don't see where I'm executing a method on `SelectedNode` ? Btw, I just created a project (WinForms) and this seems to be working perfectly, unless of course I'm totally missing the question? – Dimitar Dimitrov Dec 11 '14 at 12:06
  • My confusion. It **does** work **exactly** as you say. I didn't explained the trickery clearly enough. In each of the nodes (referred to as parents) that are reachable by index in your example, I have a set of subnodes (that I referred to as leafs). It's the leafs that need to be programmatically clicked. I can probably go *.Nodes[1].Nodes[2]* but how do I know which is the currently selected index (the one that got physically clicked by the user)? Do I need to store that value when they actually click? It seems that *.SelectedNode* already has that value in it... – Konrad Viltersten Dec 11 '14 at 12:21
  • @KonradViltersten Well, `.SelectedNode.Index` will get you the index, but be careful, if you are in a sub-sub-sub node, it will give you the index as if the tree was flat. I'll try to update the answer to explain a bit more. – Dimitar Dimitrov Dec 11 '14 at 12:30
  • 1
    No need. I can update your answer with the *weird* code I used. Change it if you see it fit. +1 for persistence. – Konrad Viltersten Dec 11 '14 at 12:32
2

Your main issue is that a Windows Forms TreeNode does not derive from a Control like a TreeView does (or, for example, a Button). It's much closer to a "model" class, meaning that it's primarily concerned with the hierarchical organization of your data. Although some of the presentational abstraction is leaked in properties like Color, Bounds, Handle and similar, a TreeNode doesn't know how to paint itself, nor how to handle click events.

On the other hand, a TreeView is an actual Control, meaning you can derive from it and be able to override its protected OnClick method, like shown in the example you linked.

If you want to follow that path, you could create your derived TreeView class from it and override the protected OnNodeMouseClick method. This method is specific to the TreeView and called by its WndProc method when a certain node is clicked.

But having read your comments to other answers, it seems that this is not what you really need to do to accomplish your goal.

Community
  • 1
  • 1
Lou
  • 4,244
  • 3
  • 33
  • 72
  • 1
    This was perfect info. I missed that in wasn't a control. You pointed out where I got mislead **and** you also explained **how** I got mislead. It's +1 for the analysis. Also, you need to change your nickname, mate. It doesn't suit you, hehe. Not with replies like this. – Konrad Viltersten Dec 11 '14 at 12:36
0

You need to use event handler for TreeView.NodeMouseClick. This Event got parameter which You can call in Your EventHandler like below:

void MyTreeview_NodeMouseClick(object sender,  
TreeNodeMouseClickEventArgs e)
{
// do something with e.Node
}
MajkeloDev
  • 1,661
  • 13
  • 30
  • It's not an answer. This occurs when you clicked on the node. It does not perform a click. – t3chb0t Dec 11 '14 at 10:32
  • Oh i missunderstood, but wait why he want to do this ? I think he should provide us some more information so we can give him somebetter solution than performing a click. – MajkeloDev Dec 11 '14 at 10:39
  • As @t3chb0t pointed out, that's what I already do. Now I need to do that "on demand" programmatically. As for the question of why, I don't see how it affects the answer to the question how. I'm not looking for a work-around, though, so a change to the approach won't suffice in this particular case, sadly. – Konrad Viltersten Dec 11 '14 at 11:30
  • _a change to the approach won't suffice in this particular case_ we cannot judge this because you did not reveal the real purpose of this to us but if you think there is no other way... so be it. – t3chb0t Dec 11 '14 at 11:34
  • @t3chb0t Just for the sake of peace of mind and satisfying other's curiosity - the task is to create a POC showing what's happening when a user clicks on the leaf. I'm creating a set of examples for some rookies showing them how events work. That's in fact the whole point in this particular case. Sorry if my reply came off as arrogant. Not intended. The task "behind the curtains" was resolved by simply filtering the data set by a property in it, when this or that radiobutton was on/off. – Konrad Viltersten Dec 11 '14 at 11:59
  • 2
    ...if so, then you might be better off with a UI testing tool where you can record/program such clicks. – t3chb0t Dec 11 '14 at 12:03
  • @t3chb0t I might be. I jus twanted to show to them that **every** component has some kind of firey thingy that gets called when there's a clicky, or righty clicky or scrolly etc. I want to say "*...and then the computer does **this***" and show them the code fire a method handling the event. Maybe I'm too over-explicit... – Konrad Viltersten Dec 11 '14 at 12:08