سؤال

إذا أردت أن تجد خانات الاختيار التحقق على صفحة ASP.NET أتمكن من استخدام الاستعلام LINQ التالية.

var checkBoxes = this.Controls
                     .OfType<CheckBox>()
                     .TakeWhile<CheckBox>(cb => cb.Checked);

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

وكان السؤال الذي يطرح هنا:

إيجاد عناصر التحكم التي تستخدم واجهة معينة في ASP.NET

وتلقى الإجابات غير LINQ، لقد سبق لي نسختي الخاصة من بحث تحكم العودية على نوع وID وسائل الإرشاد، ولكن أنا فقط أتساءل كيف يتيح هذا هو أن تفعل في LINQ؟

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

المحلول

وتأخذ من نوع / ID التحقق من العودية، بحيث يكون مجرد "أعطني كل الضوابط، بشكل متكرر" طريقة، منها مثلا.

public static IEnumerable<Control> GetAllControls(this Control parent)
{
    foreach (Control control in parent.Controls)
    {
        yield return control;
        foreach(Control descendant in control.GetAllControls())
        {
            yield return descendant;
        }
    }
}

وهذا غير فعالة إلى حد ما (من حيث خلق الكثير من التكرارات) ولكن أشك في أن سيكون لديك <م> جدا شجرة عميقة.

وبعد ذلك يمكنك إرسال الاستعلام الأصلي على النحو التالي:

var checkBoxes = this.GetAllControls()
                     .OfType<CheckBox>()
                     .TakeWhile<CheckBox>(cb => cb.Checked);

و(تحرير: تغيير AllControls إلى GetAllControls واستخدامها بشكل صحيح كأسلوب)

نصائح أخرى

public static IEnumerable<Control> AllControls(this Control container)
{
    //Get all controls
    var controls = container.Controls.Cast<Control>();

    //Get all children
    var children = controls.Select(c => c.AllControls());

    //combine controls and children
    var firstGen = controls.Concat(children.SelectMany(b => b));

    return firstGen;
}

والآن على أساس الدالة أعلاه، يمكننا أن نفعل شيئا من هذا القبيل:

public static Control FindControl(this Control container, string Id)
{
    var child = container.AllControls().FirstOrDefault(c => c.ID == Id);
    return child;
}

واقتراحي لجعل العودية AllControls هو:

    public static IEnumerable<Control> AllControls(this Control parent)
    {
        foreach (Control control in parent.Controls)
        {
             yield return control;
        }
        foreach (Control control in parent.Controls)
        {
            foreach (Control cc in AllControls(control)) yield return cc;
        }
    }

ووforeach الثانية تبدو غريبة، ولكن هذا هو السبيل الوحيد الذي أعرفه أن "تسطيح" دعوة متكررة.

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