Проблема с TreeNode.BeginEdit () - PullRequest
6 голосов
/ 06 июля 2011

Я использую WinForms TreeView и реакцию на событие AfterLabelEdit. Вот фрагмент кода:

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

Проблема в том, что когда пользователь не хочет автоматически исправлять плохой символ, узел не остается в режиме редактирования. Есть ли способ это исправить?

Ответы [ 4 ]

2 голосов
/ 17 ноября 2011

Несколько вещей, которые нужно иметь в виду:

  1. Событие AfterLabelEdit всегда завершает режим редактирования после его вызова, даже если вы вызываете BeginEdit в середине обработчика события. Вы можете использовать TreeView.BeginInvoke, чтобы «перепрыгнуть» через повторный запуск EditMode после того, как TreeView сделает свое дело. (ПРИМЕЧАНИЕ: это не создает новый поток или состояние гонки, оно просто задерживает метод для сообщения с одним окном.) Более подробная информация о некоторых проблемах с этим событием здесь (хотя это говорит о том, что я считаю худшим решением).
  2. e.Label - это null, если пользователь не внес никаких изменений, поэтому, когда мы «перепрыгиваем» с 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;
    }
0 голосов
/ 06 июля 2011

Используйте EndEdit и замените «плохой персонаж», если пользователь хочет автоматическое исправление

0 голосов
/ 30 июля 2011
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 голосов
/ 06 июля 2011

Вы можете попытаться заставить 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();

Таким образом, CancelEdit может завершиться до того, как новый BeginEdit попытается вступить во владение.

...