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