Problem with TreeNode.BeginEdit()

本文关键字:BeginEdit TreeNode with Problem | 更新日期: 2023-09-27 18:01:25

我正在使用WinForms TreeView和对AfterLabelEdit事件的反应。下面是代码片段:

if (e.Label.Contains("|"))
{
  if (WantAutofix())
  {
    label = e.Label.Replace('|', '_');
  }
  else
  {
    e.CancelEdit = true;
    e.Node.BeginEdit();
    return;
  }
}

问题是,当用户不希望自动修复坏字符时,节点不会保持在编辑模式。有办法解决这个问题吗?

Problem with TreeNode.BeginEdit()

需要注意的几点:

  1. AfterLabelEdit事件总是结束编辑模式后,它被提出,即使你调用BeginEdit在你的事件处理程序的中间。你可以使用TreeView.BeginInvoke"跳过"这有EditMode再次启动后,TreeView做它的事情。(注意:这不会创建一个新的线程或竞争条件,它只是延迟一个窗口消息的方法)这里有关于此事件的一些问题的更多信息(尽管它建议我认为是一个更糟糕的解决方案)。
  2. e.Labelnull,如果用户没有做任何改变,所以当我们"跳过"与BeginInvoke,就好像用户没有做任何改变,所以我们也需要处理这种情况。
  3. BeginInvoke在这种情况下是一个可接受的解决方案,你应该发现它在这种情况下是非常可靠的。

这对我来说工作得很好,用。net 2.0测试:

    private void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
    {
        //we have to handle both the first and future edits
        if ((e.Label != null && e.Label.Contains("|") || (e.Label == null && e.Node.Text.Contains("|"))))
        {
            if (WantAutofix())
            {
                e.CancelEdit = true;
                if(e.Label != null)
                    e.Node.Text = e.Label.Replace('|', '_');
                else
                    e.Node.Text = e.Node.Text.Replace('|', '_');
            }
            else
            {
                //lets the treeview finish up its OnAfterLabelEdit method
                treeView1.BeginInvoke(new MethodInvoker(delegate() { e.Node.BeginEdit(); }));
            }
        }
    }
    private bool WantAutofix()
    {
        return MessageBox.Show("You entered a |, you want me to AutoFix?", String.Empty, MessageBoxButtons.YesNo) == DialogResult.Yes;
    }

如果用户希望自动修复,请使用EndEdit并替换"bad character"

你可以尝试让BeginEdit()异步发生:

private void treeView1_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
    {
        if (e.Label.Contains("|"))
        {
            if (WantAutofix())
            {
            }
            else
            {
                e.CancelEdit = true;
                BeginInvoke(new ActionDelegate(new NodeBeginEditAsync(e.Node).Execute));
                return;
            }
        }
    }
public class NodeBeginEditAsync
{
    private readonly TreeNode _node;
    public NodeBeginEditAsync(TreeNode node)
    {
        _node = node;
    }
    public void Execute()
    {
        _node.BeginEdit();
    }
}
public delegate void ActionDelegate();

这样,在新的BeginEdit试图接管之前,CancelEdit就有机会完成。

try this...    
TreeNode node = tv.SelectedNode;
                    if (tv.SelectedNode.Parent == null)
                    {
                        node.TreeView.LabelEdit = false;
                    }
                    else
                    {
                        node.Text = FieldName.Text;
                        if (node == null) { return; }
                        node.TreeView.LabelEdit = true;
                        node.BeginEdit();
                    }