即使它存在Asp.Net也无法FindControl

时间:2011-12-28 20:14:17

标签: asp.net web-applications

(动态控件)在页面上Pre_Init我可以使用以下代码获取控件的名称,但即使它存在,也无法在Panel中找到控件。那为什么会这样呢?我需要做的是在处理之前获取回发控件的值。

注意:这只是一个样本。

这是HTML

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="WebForm2.aspx.vb" Inherits="DynamicControls_GetControlUnloaded.WebForm2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0    Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div style="width: 200px;">
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
        </ContentTemplate>
    </asp:UpdatePanel>
</div>
</form>
</body>
</html>

以下是Code Behind

Public Class WebForm2
Inherits System.Web.UI.Page
Dim current_val As Object

Private Sub WebForm2_PreInit(sender As Object, e As System.EventArgs) Handles Me.PreInit
    Dim postback_control As Control = GetPostBackControl(Me.Page)

    If postback_control IsNot Nothing Then
        Select Case postback_control.GetType
            Case GetType(DropDownList)
                current_val = CType(postback_control, DropDownList).Text
            Case GetType(TextBox)
                current_val = CType(postback_control, TextBox).Text
            Case GetType(CheckBox)
                current_val = CType(postback_control, CheckBox).Checked
            Case GetType(RadioButton)
                current_val = CType(postback_control, RadioButton).Checked
        End Select
    End If

End Sub

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    'Create Dynamic controls
    Call BuildControls()
End Sub

Private Sub BuildControls()
    For i As Integer = 0 To 2
        Dim ddl As New DropDownList
        ddl.Items.Add("Item 1")
        ddl.Items.Add("Item 2")
        ddl.Items.Add("Item 3")
        ddl.Style.Add("margin", "3px")
        ddl.ID = "Ctrl" & i.ToString
        ddl.AutoPostBack = True
        ddl.Width = 150
        PlaceHolder1.Controls.Add(ddl)
    Next
End Sub

Public Shared Function GetPostBackControl(ByVal thePage As Page) As Control
    Dim myControl As Control = Nothing
    Dim ctrlName As String = thePage.Request.Params.Get("__EVENTTARGET")
    If ((ctrlName IsNot Nothing) And (ctrlName <> String.Empty)) Then
        myControl = thePage.FindControl(ctrlName)
    Else
        For Each Item As String In thePage.Request.Form
            Dim c As Control = thePage.FindControl(Item)
            If (TypeOf (c) Is System.Web.UI.WebControls.Button) Then
                myControl = c
            End If
        Next
    End If
    Return myControl
End Function

End Class

4 个答案:

答案 0 :(得分:0)

您可以使用Pre_Init进入处理步骤的早期阶段。你的代码真的必须在那里运行吗?请参阅MSDN中有关生命周期事件的this article

答案 1 :(得分:0)

Init事件是你最好的选择。我认为Pre-Init用于母版页。视图状态在Init事件之前加载。

答案 2 :(得分:0)

我的建议是在Init中创建控件而不是在Load中创建控件,然后创建所有控件。这将使这些对象的所有事件被触发(因为您在分析ViewState之前创建它们)。然后,您可以从控件本身获得所需的值。如果需要根据值显示不同的内容,请创建所有对象,然后隐藏您不想显示的对象(.Visible = false)。它们将在ASP.NET雷达上,除非它们不会被渲染。

答案 3 :(得分:-1)

页面Pre_init上没有

FlowLayoutPanel2,因为它仅在客户端可用。为什么不使用<asp:Dropdownlist>

如果您必须使用选择选项,则可以通过添加<select和/或将其添加到runat="server"来访问<div id="FlowLayoutPanel2",以便从服务器端访问这两个选项。

    <div id="FlowLayoutPanel2" style="width:300px;padding-bottom:10px;padding-left:10px;padding-right:10px;" runat="server">
        <span>Select type of item:</span>
        <select name="ctrl1" runat="server" ...>
            <option selected="selected" value=""></option>
            <option value="Item 1">Item 1</option>
            <option value="Item 2">Item 2</option>
            <option value="Item 3">Item 3</option>
            <option value="Item 4">Item 4</option>
        </select>
    </div>