ASP.Net FindControl不工作 - 怎么样?

Lil*_*oke 29 .net c# asp.net findcontrol

我曾经FindControl在.NET 2.0/3.0之前使用过.现在看来,由于某些原因,我的控件的ID会被分配一个时髦的名字.例如,我为复选框分配了一个id"cbSelect",但FindControl找不到它.当我查看它被分配的HTML时ctl00_bodyPlaceHolder_ctl02_cbSelect.

我还没有找到提到它的FindControl的一个例子.事实上,每个人似乎都像正常一样使用find控件.

那么,我做错了什么?.Net改变了吗?任何人都可以为我解释这一点,这真的令人沮丧!

Ale*_*ris 29

您可能正在使用MasterPage或用户控件(ascx),这就是客户端ID更改的原因.想象一下,您在母版页中有一个控件,其ID与页面中的控件相同.这会导致冲突.id更改确保所有ClientID属性在页面上都是唯一的.

使用MasterPages时,FindControl需要特别注意.看看ASP.NET 2.0 MasterPages和FindControl().FindControl在命名容器内部工作.MastePage和页面是不同的命名容器.

  • 微软实现这一点的方式就是这样一个笑话,应该可行.哦,你有一个主页?500个嵌套母版页怎么样?该方法应该弄明白并做必要的事情来找到控制期. (10认同)

nem*_*mke 10

您可以编写扩展程序以使用递归在页面上查找任何控件.这可能在某些Util/Helper类中.

 public static Control FindAnyControl(this Page page, string controlId)
    {
        return FindControlRecursive(controlId, page.Form);
    }

    public static Control FindAnyControl(this UserControl control, string controlId)
    {
        return FindControlRecursive(controlId, control);
    }

    public static Control FindControlRecursive(string controlId, Control parent)
    {
        foreach (Control control in parent.Controls)
        {
            Control result = FindControlRecursive(controlId, control);
            if (result != null)
            {
                return result;
            }
        }
        return parent.FindControl(controlId);
    }
Run Code Online (Sandbox Code Playgroud)


Ste*_*edd 8

通过简单的扩展方法,我在"大多数"案例中解决了这个问题

您可以在您认为最好的任何更高级别的容器控件上调用它,包括页面本身(如果您要扫描整个控件层次结构).

private static Control FindControlIterative(this Control control, string id)
{
    Control ctl = control;

    LinkedList<Control> controls = new LinkedList<Control>();

    while(ctl != null)
    {
        if(ctl.ID == id)
        {
            return ctl;
        }

        foreach(Control child in ctl.Controls)
        {
            if(child.ID == id)
            {
                return child;
            }

            if(child.HasControls())
            {
                controls.AddLast(child);
            }
        }

        ctl = controls.First.Value;
        controls.Remove(ctl);
    }

    return null;
}
Run Code Online (Sandbox Code Playgroud)


小智 7

在控件集合中搜索控件时,请始终使用您为控件分配的ID,而不是您在源文章渲染中看到的ID.如果FindControl()找不到您知道的控件,则很可能您没有在控件层次结构的正确分支中进行搜索.递归函数对我来说是成功的.

这是我用于VB.NET 3.5的示例:

Function FindControlRecursive(ByVal ctrl As Control, ByVal id As String) As Control
    Dim c As Control = Nothing

    If ctrl.ID = id Then
        c = ctrl
    Else
        For Each childCtrl In ctrl.Controls
            Dim resCtrl As Control = FindControlRecursive(childCtrl, id)
            If resCtrl IsNot Nothing Then c = resCtrl
        Next
    End If

    Return c
End Function
Run Code Online (Sandbox Code Playgroud)

这是一个如何在我的基页类中局部实现此函数的示例:

Dim form HtmlForm = CType(FindControlRecursive(Me, "Form"), HtmlForm)
Run Code Online (Sandbox Code Playgroud)