Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with TreeNode.BeginEdit()

I'm using WinForms TreeView 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?

like image 956
Migol Avatar asked Jul 06 '11 13:07

Migol


1 Answers

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;
    }
like image 59
Kevin McCormick Avatar answered Sep 19 '22 11:09

Kevin McCormick