Lent TreeNode avec CheckBoxes [grande quantité]
Question
chèques d'événements AfterCheck Tree Voir contrôle tous les nœuds enfants en dessous et permet le bouton Exécuter si quelque chose est cochée.
1346 void TreeNode_AfterCheck(object sender, TreeViewEventArgs e) {
1347 if (!e.Node.Checked) return;
1348 foreach (TreeNode sub in e.Node.Nodes) {
1349 sub.Checked = e.Node.Checked;
1350 }
1351 RunButton.Enabled = IsANodeChecked();
1352 }
1429 static bool IsANodeChecked(TreeNode node) {
1430 if (node.Checked) return true;
1431 foreach (TreeNode sub in node.Nodes) {
1432 if (IsANodeChecked(sub)) {
1433 return true;
1434 }
1435 }
1436 return false;
1437 }
Vérification du nœud racine quand il y a des nœuds 4881 sous l'interface graphique va se bloquer pendant environ 7 secondes.
Je ne dois appeler IsANodeChecked (sur la ligne 1351) une fois, mais je ne sais pas comment le désactiver avant que tous les nœuds d'arbres ont été traités.
Et je ne veux pas avoir une minuterie sur mon formulaire consacré au suivi de cela.
quiconque ne voit une solution simple, / évidente?
La solution 3
Ces idées où utile, mais je utilisé quelque chose de différent qui a travaillé en ajoutant une seule variable booléenne:
bool _treeNodeFirst = false;
... et un événement vérifié avant qui modifie temporairement la couleur Retour sur le contrôle pour servir de drapeau pour le contrôle qui a commencé la chaîne des événements:
1273 void TreeNode_BeforeCheck(object sender, TreeViewCancelEventArgs e) {
1274 if (!_treeNodeFirst) {
1275 _treeNodeFirst = true;
1276 e.Node.BackColor = Color.Silver;
1277 }
1278 }
1346 void TreeNode_AfterCheck(object sender, TreeViewEventArgs e) {
1347 if (e.Node.Checked) {
1348 foreach (TreeNode sub in e.Node.Nodes) {
1349 sub.Checked = e.Node.Checked;
1350 }
1351 }
1352 if (e.Node.BackColor == Color.Silver) {
1353 e.Node.BackColor = Color.Empty;
1354 RunButton.Enabled = IsANodeChecked();
1355 _treeNodeFirst = false;
1356 }
1357 }
1429 static bool IsANodeChecked(TreeNode node) {
1430 if (node.Checked) return true;
1431 foreach (TreeNode sub in node.Nodes) {
1432 if (IsANodeChecked(sub)) {
1433 return true;
1434 }
1435 }
1436 return false;
1437 }
Cela semble être la meilleure façon (que je peux voir en ce moment) pour faire en sorte que IsANodeChecked(TreeNode)
n'est exécuté qu'une seule fois quand un groupe de noeuds est sélectionné à la fois.
Je fais cependant vraiment l'idée de Jimmy Hoffa d'utiliser un compte, cependant. Je vais probablement l'ajouter à mon code.
Merci à tous! ~ Joe
Autres conseils
Mettre un gestionnaire d'événements sur vos cases à cocher qui active ou désactive le RunButton plutôt que d'avoir quelque chose qui itère sur la chose à savoir.
Ajoutez la case à cocher à une liste de cases à cocher cochées quand il se est cochée d'abord si vous ne désactivez pas le RunButton jusqu'à ce que la liste des cases cochées est vide. Retirer de la liste quand il est décochée, etc.
Voici genre de comment je l'écrire, cela est tout simplement désolé l'improvisation si je manque quelque chose:
private int _checkedCheckboxes;
void AddCheckBox()
{
if (_checkedCheckBoxes++ == 1) RunButton.Enabled = true;
}
void RemoveCheckBox()
{
if (_checkedCheckBoxes-- == 0) RunButton.Enabled = false;
}
void TreeNode_AfterCheck(object sender, TreeViewEventArgs e)
{
if (e.Node.Checked)
{
AddCheckBox();
return;
}
RemoveCheckBox();
}
J'utilise parfois Timer
pour traiter ces cas. Ajoutez une minuterie et mettre en place le gestionnaire d'événements Tick
à IsANodeChecked
d'appel et activer / désactiver le bouton. Donnez-lui un court intervalle (~ 100 ms peut-être), et le laisser désactivé. , Vous appelez ensuite Stop
suivi par Start
la minuterie dans votre gestionnaire d'événements AfterCheck
. Cela entraînera la minuterie à redémarrer pour chaque appel à AfterCheck
, mais le gestionnaire d'événements Tick
sera invoqué que lorsqu'un certain temps est écoulé après l'appel Start
, ce qui signifie qu'il ne sera pas invoqué qu'après le dernier appel à AfterCheck
.
100 ms est très de temps pour l'ordinateur au travail, mais semble immédiat pour l'utilisateur.
Vous pouvez voir un comportement similaire dans Windows Explorer. Si vous utilisez le clavier pour déplacer rapidement naviguer dans l'arborescence des dossiers, le volet de droite avec le contenu du dossier ne sera pas mise à jour, sauf si vous restez sur un dossier dans l'arbre pour un moment bref.