سؤال

يتحقق الحدث بعد تحكم Tree View Control من جميع العقد الفرعية الموجودة أسفله ويمكّن زر التشغيل إذا تم التحقق من شيء ما.

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 }

التحقق من عقدة الجذر عندما يكون هناك 4881 العقد الفرعية سوف تعلق واجهة المستخدم الرسومية لمدة 7 ثوانٍ تقريبًا.

أنا فقط بحاجة إلى استدعاء isanodechecked (على السطر 1351) مرة واحدة ، لكنني لا أعرف كيفية تعطيلها حتى تتم معالجة جميع العقد الشجرة.

وأنا لا أريد أن يكون لدي مؤقت في النموذج الخاص بي مخصص لمراقبة هذا.

هل يرى أي شخص حلًا بسيطًا/واضحًا؟

هل كانت مفيدة؟

المحلول 3

هذه الأفكار حيث تكون مفيدة ، لكنني استخدمت شيئًا مختلفًا يعمل عن طريق إضافة متغير منطقي واحد:

bool _treeNodeFirst = false;

... وحدث قبل التحقق من تعديل اللون الخلفي مؤقتًا على عنصر التحكم ليكون بمثابة علامة للتحكم الذي بدأ سلسلة الأحداث:

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 }

يبدو أن هذه هي أفضل طريقة (يمكنني رؤيتها الآن) لضمان ذلك IsANodeChecked(TreeNode) يتم تشغيله مرة واحدة فقط عند اختيار مجموعة من العقد في وقت واحد.

ومع ذلك ، أحب حقًا فكرة جيمي هوفا عن استخدام عدد. ربما سأضيف ذلك إلى الكود الخاص بي.

شكرا للجميع! ~ جو

نصائح أخرى

ضع معالج الأحداث على مربعات الاختيار التي تمكن أو تعطيل Runbutton بدلاً من وجود شيء يكرر الأمر كله لمعرفة ذلك.

أضف مربع الاختيار إلى قائمة مربعات الاختيار التي تم تحديدها عندما يتم فحصها أولاً حتى لا تقوم بتعطيل Runbutton حتى تصبح قائمة مربعات الاختيار التي تم فحصها فارغة. قم بإزالتها من القائمة عندما يتم عدم رادعها ، إلخ.

إليك نوعًا ما من كيفية كتابته ، هذا مجرد تجنيده آسف جدًا إذا فاتني شيء ما:

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();
}

أستخدم أحيانًا أ Timer للتعامل مع مثل هذه الحالات. أضف مؤقتًا وقم بإعداد ملف Tick معالج الأحداث للاتصال IsANodeChecked وتمكين/تعطيل الزر. امنحه فاصلًا قصيرًا (~ 100 مللي ثانية ربما) ، واتركه معاقًا. ثم تتصل Stop تليها Start على الموقت في الخاص بك AfterCheck معالج الأحداث. سيؤدي ذلك إلى إعادة تشغيل المؤقت لكل مكالمة AfterCheck, ، لكن ال Tick لن يتم استدعاء معالج الأحداث إلا عند انقضاء وقت معين بعد Start مكالمة ، مما يعني أنه لن يتم الاحتجاج به حتى بعد آخر مكالمة إلى AfterCheck.

100 مللي ثانية جداً وقت طويل حتى يعمل الكمبيوتر ، ولكن سيبدو فوريًا للمستخدم.

يمكنك رؤية سلوك مماثل في مستكشف Windows. إذا كنت تستخدم لوحة المفاتيح للتنقل بسرعة في شجرة المجلد ، فلن يتم تحديث جزء اليد اليمنى مع محتويات المجلد إلا إذا بقيت على مجلد في الشجرة للحظة وجيزة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top