开发者

Problem with TreeNode.BeginEdit()

I'm using WinForms TreeView开发者_如何学JAVA and reaction to AfterLabelEdit event. Here's the snippet of the code:

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

The problem is that when user doesn't want automatic fix of bad character, node doesn't stay in edit mode. Any way to fix this?


A few things to keep in mind:

  1. The AfterLabelEdit event always ends edit mode after it is raised, even if you call BeginEdit in the middle of your event handler. You can use TreeView.BeginInvoke to "leapfrog" this by having EditMode start up again after the TreeView does its thing. (NOTE: this does not create a new thread or race condition, it simply delays the method for 1 window message.) There is more information on some of the issues with this event here (though it suggests what I think is a worse solution).
  2. e.Label is null if the user didn't make any changes, so when we "leapfrog" with BeginInvoke, it is as if the user didn't make any changes, so we also need to handle that case.
  3. BeginInvoke is an acceptable workaround in this case, you should find it to be very reliable in this situation.

This works very well for me, tested with .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;
    }


Use EndEdit and Replace the "bad character" if user want automatic fix


You could try making the BeginEdit() occur asynchronously:

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

That way the CancelEdit is given a chance to complete before a new BeginEdit tries to take over.


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜