Я пытаюсь написать метод расширения для System.Web.UI.Control
, который будет искать в ControlCollection
экземпляр конкретного Type
и возвращать первый найденный экземпляр. Первая глубина проста, однако сначала я хочу найти ширину, чтобы более высокие коллекции имели приоритет.
Мой текущий метод некорректен и рано завершает работу, возвращая ноль в некоторых случаях, когда весь поиск не был завершен. Я надеюсь, что я близок к правильному решению, но мне нужно взглянуть на него свежим взглядом. Есть предложения?
public static T FindFirstControlOfType<T>(this Control rootControl, bool searchRecursively) where T : Control
{
// list for container controls
List<Control> controlsWithChildren = new List<Control>();
// iterate the current control collection first
foreach (Control child in rootControl.Controls)
{
if (child.GetType().IsAssignableFrom(typeof(T)))
{
return (T)child;
}
// track those controls containing children
if (child.HasControls())
{
controlsWithChildren.Add(child);
}
}
// if recursion is enabled, search the child nodes
if (searchRecursively)
{
foreach (Control control in controlsWithChildren)
{
return FindFirstControlOfType<T>(control, true);
}
}
// if never found, return null
return null;
}
РЕДАКТИРОВАТЬ - Рабочий раствор на основе отмеченного ответа, для всех, кто заинтересован:
public static T FindFirstControlOfType<T>(this Control rootControl, bool searchNestedControls) where T : Control
{
Queue<Control> queue = new Queue<Control>();
EnqueueChildControls(queue, rootControl);
while (queue.Count > 0)
{
Control current = queue.Dequeue();
if (current.GetType() == typeof(T))
{
return (T)current;
}
if (searchNestedControls)
{
EnqueueChildControls(queue, current);
}
}
return null;
}
private static void EnqueueChildControls(Queue<Control> queue, Control control)
{
foreach (Control current in control.Controls)
{
queue.Enqueue(current);
}
}