Проблема с TreeNode.Метод beginedit()
Я использую WinForms TreeView
и реакция на AfterLabelEdit
событие. Вот фрагмент кода:
if (e.Label.Contains("|"))
{
if (WantAutofix())
{
label = e.Label.Replace('|', '_');
}
else
{
e.CancelEdit = true;
e.Node.BeginEdit();
return;
}
}
проблема в том, что когда пользователь не хочет автоматического исправления плохого символа, узел не остается в режиме редактирования. Как это исправить?
4 ответов
несколько вещей, чтобы иметь в виду:
- на
AfterLabelEdit
событие всегда завершает режим редактирования после его возникновения, даже если вы вызываетеBeginEdit
в середине обработчика событий. Вы можете использоватьTreeView.BeginInvoke
чтобы "перепрыгнуть" это, запустив EditMode снова после того, как TreeView сделает свое дело. (Примечание: это не создает новый поток или состояние гонки, он просто задерживает метод для 1 сообщения окна.) есть дополнительная информация о некоторых проблемах с этим событием здесь (хотя он предполагает, что я думаю, что это худшее решение). -
e.Label
isnull
если пользователь не внес никаких изменений, поэтому, когда мы "прыгаем" с 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;
}
вы можете попробовать сделать 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 попытается взять на себя.
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();
}