【问题标题】:Unable to change selectedNode in a treeView during AfterLabelEdit在 AfterLabelEdit 期间无法更改 treeView 中的 selectedNode
【发布时间】:2011-11-23 01:29:42
【问题描述】:

我在树视图中选择的节点有问题。

这里有两种情况。 (#2是我的问题)

1 - 如果我选择节点“级别”,请按 F2,更改标签并按 Enter。 AfterLabelEdit 中的 selectedNode 将发生变化。 selectedNode 将从“Level1”变为“Root”。

2 - 如果我选择节点“级别”,按 F2,更改标签但单击树视图上的某个位置,则 selectedNode 将永远不会改变。

是导致问题的事件触发吗?

我创建了一个小型测试项目来展示手头的问题。

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];
}

}

【问题讨论】:

    标签: c# winforms treeview treenode


    【解决方案1】:

    这是一个事件顺序问题,鼠标点击触发 after AfterLabelEdit 所以它获胜。典型的 BeginInvoke 技巧不起作用,您需要一个 Timer 来选择节点:

        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();
            };
        }
    

    这行得通,有点难看。这仅在用户单击特定节点时发生,也许您不应该覆盖该选择。顺便说一句,复制代码的荣誉。

    【讨论】:

    • 谢谢汉斯,我明天上班后试试。如果这不起作用,我可能只是将伪造/复制 selectedNode 添加到继承的树视图中。
    • 嗨,汉斯,我最终重构了我的方法,不必使用 SelectedNode。我想知道这是否会被视为树视图控件中的错误..?
    • 不,这完全是设计使然。正如我所说,Windows 将用户放在首位,如果她单击一个节点来选择它,那么她会很高兴地选择该节点。你正在与系统作斗争。这不是一个好主意,它只会让用户感到困惑。
    【解决方案2】:

    有点骇人听闻,但是当用户单击树视图中的其他位置时,这将选择根节点,除了 level2 节点:

    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;
            }
    
        }
    

    把它放在你的 form1 构造函数中:

        this.treeView1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.treeView1_MouseDown);
    

    【讨论】:

    • 感谢您的回答。我调查了鼠标按下事件。我的示例是我的代码的低调版本。我需要在 AfterLabelEdit 事件中更改选定的节点(以避免必须进行大的重构以从使用中删除 selectedNode)。
    • 是的,据我所知,编辑模式中的某些东西正在吞噬点击事件并阻止所选节点在点击时发生变化。
    猜你喜欢
    • 2014-06-17
    • 2012-01-11
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多