1

いくつかのイベントを表示するカレンダーをコーディングしています。毎日、朝、午後、夜のイベント用のボタンがあり、イベントがある場合は、ボタンが有効になっていることを示し、色が変わります。これらのボタンを html テーブルに表示していますが、誰かが表示されている月を変更すると、プログラムはボタンをすべて無効にして色を再び白に設定することでボタンを「クリーンアップ」する必要があります。次のように、ボタンを含むテーブルで FindControl メソッドを使用して、それらを有効にすることができました。

string butControl = /* id of the button */
Button block = mainTable.FindControl(butControl) as Button;
block.BackColor = Color.Gray;
block.Enabled = true;

そして、それはうまくいきます。私のクリーンアップ メソッドでは、105 個あるため、ボタンのすべての名前を呼び出したくありません。代わりに、次のメソッドを使用しました。

    private void CleanUp()
    {
        foreach (Control c in mainTable.Controls)
        {
            Button bot = c as Button;
            if (bot != null)
            {
                bot.BackColor = Color.White;
                bot.Enabled = false;
            }
        }
    }

ただし、これによってボタンの色や有効なプロパティが変更されることはありません。私の質問は: テーブルの Controls プロパティのコントロールは、FindControl メソッドを介して見つけることができるものと同じではありませんか? または、コントロールを取得するときに何か間違ったことをしていますか?

4

2 に答える 2

2

階層ではなく、コントロールのリストを反復しているという問題はありませんか? FindControl は階層を使用します。次のようにコントロールをループできます。

public IEnumerable<T> EnumerateRecursive<T>(Control root) where T : Control
{
    Stack<Control> st = new Stack<Control>();
    st.Push(root);

    while (st.Count > 0)
    {
        var control = st.Pop();
        if (control is T)
        {
            yield return (T)control;
        }

        foreach (Control child in control.Controls)
        {
            st.Push(child);
        }
    }
}

public void Cleanup() 
{
    foreach (Button bot in EnumerateRecursive<Button>(this.mainTable))
    {
        bot.BackColor = Color.White;
        bot.Enabled = false;
    }
}

再帰を使用して実装することもできますが、スタックの方がはるかに高速であるため、通常はスタックを好みます。

于 2013-01-17T06:44:18.990 に答える
0

ASP テーブルを使用していると仮定しますが、それは確実に機能しません。他の方法で回避することもできますが、HTML を使用することが重要でない場合は、次のように再構成することをお勧めします。

<form id="form1" runat="server">
    <asp:Panel ID="mainTable" runat="server">
        <table>
            <tr>
                <td>
                    <asp:Button ID="Button1" runat="server" Text="Button" />
                </td>
            </tr>
        </table>
    </asp:Panel>
</form>

実際のボタンを除いて、asp:Panel 内で html コントロールのみを使用していることに注意してください。ASP を使用すると、子を再帰的に探す必要があります。

編集: 子供を再帰的に探すと言えば、Stefan は私が書き終える前にその正確な提案とコードを提供しました。私は間違いなく彼の方法をお勧めします。彼は明らかに私よりずっと怠け者ではありません。

==================================

Stefan のアプローチには、型を知らずに明示的に型キャストすることはできず、ジェネリックを使用すると型を知ることができないという点で、わずかな誤りがあります。これは、あなたが使用しているように、純粋にボタンで使用するための怠惰な適応です。

この「回答」ステータスを与えないでください。それは他人の作品の破損です。

public IEnumerable<Button> EnumerateRecursive(Control root)
{
    // Hook everything in Page.Controls
    Stack<Control> st = new Stack<Control>();
    st.Push(root);

    while (st.Count > 0)
    {
        var control = st.Pop();
        if (control is Button)
        {
            yield return (Button)control;
        }

        foreach (Control child in control.Controls)
        {
            st.Push(child);
        }
    }
}

public void Cleanup()
{
    foreach (Button bot in EnumerateRecursive(this.mainTable))
    {
        bot.BackColor = Color.White;
        bot.Enabled = false;
    }
}
于 2013-01-17T06:48:10.220 に答える