控制属性和FindControl函数C#

时间:2013-01-17 06:23:04

标签: c# asp.net controls

我正在编写一个显示某些事件的日历。每天都有一个按钮,用于上午,下午和夜晚活动,当有事件显示按钮已启用且颜色已更改时。我在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方法找到?或者我在检索控件时做错了什么?

2 个答案:

答案 0 :(得分: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;
    }
}

你也可以使用递归来实现它,但我通常更喜欢堆栈,因为它更快。

答案 1 :(得分: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;
    }
}