37

ASP.NET ページでオンになっているチェック ボックスを見つけたい場合は、次の LINQ クエリを使用できます。

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

チェックボックスが現在のコントロール コレクションにネストされている場合は問題なく動作しますが、最上位コントロールのコントロール コレクションにドリルダウンして検索を拡張する方法を知りたいです。

ここで質問されました:

ASP.NET で特定のインターフェイスを使用するコントロールを見つける

LINQ 以外の回答を受け取りました。拡張メソッドとして型と ID の再帰的制御検索の独自のバージョンを既に持っていますが、LINQ でこれを行うのがどれほど簡単か疑問に思いましたか?

4

3 に答える 3

47

タイプ/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 に変更し、メソッドとして適切に使用します。)

于 2008-10-31T15:43:57.823 に答える
2
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;
}
于 2011-03-03T19:08:28.323 に答える
0

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

2 番目foreachは奇妙に見えますが、これが再帰呼び出しを「平坦化」する唯一の方法です。

于 2008-10-31T16:10:53.433 に答える