بحث تحكم عودي مع LINQ
-
05-07-2019 - |
سؤال
إذا أردت أن تجد خانات الاختيار التحقق على صفحة 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
الثانية تبدو غريبة، ولكن هذا هو السبيل الوحيد الذي أعرفه أن "تسطيح" دعوة متكررة.