私はControlCollection
の特定のType
のインスタンスを検索し、見つかった最初のインスタンスを返すSystem.Web.UI.Control
の拡張メソッドを作成しようとしています。深さ優先は単純ですが、より高いコレクションが優先されるように、まず幅を検索したいと思います。C#コントロールコレクションの幅広い最初の検索
私の現在のメソッドには欠陥があり、早期に終了し、検索全体が完了しなかった場合にnullを返します。私は正しい解決策に近いと思っていますが、それに対して新鮮な目が必要です。助言がありますか?
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;
}
EDIT - 作業溶液マークされた回答に基づいて、興味がある人のために:
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);
}
}
ありがとうAndre - 私はこれを実装しようとします。幅広い最初の検索が必要なので、私は錆びているので、しばらくしています。 –
私もそうでしたが、最近私はBFSをする必要がありました。そして私は実装が簡単ではなかったことを思い出しました。幸運にも、もし助けが必要なら私たちに知らせてください。 –
サイドノートでは、再帰を使用するのではなく、キューをスタックに変更するだけで、このBFSを深さに変えることができます。また、優先順位キューを使用して、最善の検索を行うこともできます。すべてのインターフェイスが共通の場合は、単純な構成変更によってアルゴリズム全体が変更されます。クール。 – Servy