Следующий код взят непосредственно от 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's 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 AfterCheck. Это затем рекурсивно проверяет или сняло флажок с дочерними узлами на treeview.
Однако, если Вы на самом деле пробуете его и несколько раз нажимаете на тот же treeview флажок достаточно быстро, дочерние узлы заканчиваются со своей проверкой, несинхронизированной с родителем. Вам, вероятно, нужны несколько уровней детей с, возможно, 100 детьми всего для обновления UI, чтобы быть достаточно медленными для замечания этого случая.
Я попробовал несколько вещей (таких как отключение управления treeview в начале node_AfterCheck и перевключения в конце), но несинхронизированная проблема все еще происходит.
Какие-либо идеи?
Класс .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);
}
}