Unable to change selectedNode in a treeView during AfterLabelEdit
I'm having an issue with the selected node in a treeview.
Here is are two scenario. (# 2 is causing my problem)
1 - If I select the node "level", press F2, change the label and press enter. The selectedNode inside the AfterLabelEdit will change. The selectedNode will change from "Level1" to "Root".
2 - If I select the node "level", press F2, change the label but click somewhere on the treeview, the selectedNode will never change.
Is an event firing that is causing the issue?
I'v开发者_如何转开发e created a small test project to show the issue at hand.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Load += new EventHandler(Form1_Load);
this.treeView1.KeyDown += new KeyEventHandler(Form1_KeyDown);
this.treeView1.AfterLabelEdit += new NodeLabelEditEventHandler(treeView1_AfterLabelEdit);
}
void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
{
Console.WriteLine(this.treeView1.SelectedNode);
this.treeView1.SelectedNode = this.treeView1.SelectedNode.Parent;
Console.WriteLine(this.treeView1.SelectedNode);
TreeNode test = this.treeView1.SelectedNode;
}
void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (this.treeView1.SelectedNode != null)
{
if (e.KeyData == Keys.F2)
{
this.treeView1.SelectedNode.BeginEdit();
}
}
base.OnKeyDown(e);
}
void Form1_Load(object sender, EventArgs e)
{
this.treeView1.Nodes.Add(new TreeNode("root"));
this.treeView1.Nodes[0].Nodes.Add(new TreeNode("level1"));
this.treeView1.Nodes[0].Nodes[0].Nodes.Add(new TreeNode("level2"));
this.treeView1.SelectedNode = this.treeView1.Nodes[0];
this.treeView1.SelectedNode.ExpandAll();
this.treeView1.SelectedNode = this.treeView1.Nodes[0].Nodes[0];
}
}
It is an event order problem, the mouse click fires after AfterLabelEdit so it wins. The typical BeginInvoke trick doesn't work, you'll need a Timer to select the node:
void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e) {
TreeNode nextnode = this.treeView1.SelectedNode.Parent;
var timer = new Timer() { Enabled = true, Interval = 50 };
timer.Tick += delegate {
this.treeView1.SelectedNode = nextnode;
timer.Dispose();
};
}
That works, kinda ugly. This only happens when the user clicks a specific node, maybe you should not override the choice. Kudos for the repro code btw.
Kinda a hack, but this will select the root node when the user clicks somewhere else in the treeview, except for the level2 node:
private bool SelectParent = false;
void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
{
this.treeView1.SelectedNode = e.Node.Parent;
SelectParent = true;
}
private void treeView1_MouseDown(object sender, MouseEventArgs e)
{
if (SelectParent)
{
this.treeView1.SelectedNode = this.treeView1.SelectedNode.Parent;
SelectParent = false;
}
}
put this in your form1 constructor:
this.treeView1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.treeView1_MouseDown);
精彩评论