Winforms treeview, рекурсивно проверяет проблему с дочерними узлами
Следующий код берется непосредственно от Microsoft по адресу http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.aftercheck%28VS.80%29.aspx.
// Updates all child tree nodes recursively.
private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
{
foreach (TreeNode node in treeNode.Nodes)
{
node.Checked = nodeChecked;
if (node.Nodes.Count > 0)
{
// If the current node has child nodes, call the CheckAllChildsNodes method recursively.
this.CheckAllChildNodes(node, nodeChecked);
}
}
}
// NOTE This code can be added to the BeforeCheck event handler instead of the AfterCheck event.
// After a tree node Checked property is changed, all its child nodes are updated to the same value.
private void node_AfterCheck(object sender, TreeViewEventArgs e)
{
// The code only executes if the user caused the checked state to change.
if (e.Action != TreeViewAction.Unknown)
{
if (e.Node.Nodes.Count > 0)
{
/* Calls the CheckAllChildNodes method, passing in the current
Checked value of the TreeNode whose checked state changed. */
this.CheckAllChildNodes(e.Node, e.Node.Checked);
}
}
}
Вы помещаете его в форму, содержащую treeview, и вызываете node_AfterCheck (неожиданность, неожиданность), событие TreeView treeview. Затем он рекурсивно проверяет или отменяет дочерние узлы в дереве.
Однако, если вы на самом деле попробуете его и достаточно быстро нажмите несколько раз на одном и том же дереве, дочерние узлы получат синхронизацию с родителем. Вероятно, вам потребуется несколько уровней детей, у которых, возможно, 100 детей в целом для обновления пользовательского интерфейса, будут достаточно медленными, чтобы заметить это.
Я пробовал пару вещей (например, отключить элемент управления treeview в начале node_AfterCheck и повторное включение в конце), но проблема с отсутствием синхронизации все еще происходит.
Любые идеи?
Ответы
Ответ 1
Класс .NET TreeView сильно настраивает обработку мыши для собственного элемента управления Windows, чтобы синтезировать события до и после. К сожалению, они не поняли это правильно. Когда вы начнете быстро нажимать, вы будете генерировать сообщения с двойным щелчком. Нативный элемент управления реагирует на двойной щелчок, переключая проверенное состояние для элемента, не сообщая об обертке .NET об этом. Вы не получите событие Before/AfterCheck.
Это ошибка, но они не исправят ее. Обходной путь не является сложным, вам нужно не допустить, чтобы собственный элемент управления видел событие двойного щелчка. Добавьте новый класс в свой проект и вставьте код, показанный ниже. Компиляция. Снимите новый элемент управления с верхней части панели инструментов, заменив существующий.
using System;
using System.Windows.Forms;
class MyTreeView : TreeView {
protected override void WndProc(ref Message m) {
// Filter WM_LBUTTONDBLCLK
if (m.Msg != 0x203) base.WndProc(ref m);
}
}