动态加载UserControl加载DropDownList项一旦消失在PostBack上

时间:2015-03-24 14:49:58

标签: vb.net visual-studio webforms user-controls

技术:Asp.Net 4.5

我有一个可能会加载数百个不同动态用户控件的项目。当然,一次一个,取决于用户选择。 usercontrol接口将在加载时从数据库中填充。

使用下拉列表动态加载用户控件时,我只想加载一次项目。然而,这些项目在回发时消失了。我在usercontrol中使用Page_Load来填充下拉列表。我也尝试过OnInit。到目前为止,我没有尝试过任何工作。

奇怪的是,如果我从主页面调用usercontrol中的方法,则每次回发都会保留项目,而不必每次都重新填充项目。

我希望在添加用户控件时加载一次项目。这是示例代码(非常简单)

MainPage - Aspx

<%@ Page Language="vb" AutoEventWireup="false"   CodeBehind="WebForm5.aspx.vb" Inherits="WebApplication1.WebForm5" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
<form id="form1" runat="server">
    <div>
        <asp:Button ID="Button1" runat="server" Text="Load User Control" />
        <asp:Button ID="Button2" runat="server" Text="PostBack" />
        <asp:Button ID="Button3" runat="server" Text="Invoke Method" />
        <asp:Panel ID="Panel1" runat="server">
        </asp:Panel>
    </div>
</form>
</body>
</html>

MainPage - CodeBehind

Public Class WebForm5
Inherits System.Web.UI.Page

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Request.Form(Button1.UniqueID) IsNot Nothing Then
        Session("IsLoading") = True
        Panel1.Controls.Clear()
    End If

    If IsPostBack = True Then
        Dim MyControl As UserControl = Page.LoadControl("UserControls\UcTest.ascx")
        MyControl.ID = "UcTest"
        MyControl.EnableViewState = True
        Panel1.Controls.Add(MyControl)
    End If

End Sub

Protected Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click

    Dim uc As UserControl = Panel1.FindControl("UcTest")
    If uc IsNot Nothing Then
        Dim s As String = ""
        Dim method As System.Reflection.MethodInfo = uc.GetType.GetMethod("LoadItems")
        If method IsNot Nothing Then
            method.Invoke(uc, New Object() {s})
        End If
    End If

End Sub

End Class

编辑 - 根据Ann的回答解决了这个问题。使用PreInit而不是Page_Load

  Private Sub WebForm5_PreInit(sender As Object, e As EventArgs) Handles Me.PreInit
    If Request.Form(Button1.UniqueID) IsNot Nothing Then
        Session("IsLoading") = True
        Panel1.Controls.Clear()
    End If

    If IsPostBack = True Then
        Panel1.Controls.Clear()
        Dim MyControl As UserControl = Page.LoadControl("UserControls\UcTest.ascx")
        MyControl.ID = "UcTest"
        MyControl.EnableViewState = False
        Panel1.Controls.Add(MyControl)
        MyControl.EnableViewState = True
    End If

End Sub

UserControl - Aspx

<%@ Control Language="vb" AutoEventWireup="false" CodeBehind="UcTest.ascx.vb" Inherits="WebApplication1.UcTest" %>

<br />
<asp:DropDownList ID="DropDownList1" runat="server" Width="150" AutoPostBack="false" EnableViewState="True">
</asp:DropDownList>

UserControl - CodeBehind

Public Class UcTest
Inherits System.Web.UI.UserControl

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Session("IsLoading") = True Then

        'To be populated from database in the real app
        'Simplified here for testing

        DropDownList1.Items.Add("Red")
        DropDownList1.Items.Add("Green")
        DropDownList1.Items.Add("Blue")
        Session("IsLoading") = False
    End If

End Sub

Public Sub LoadItems(s As String)
    DropDownList1.Items.Add("Red")
    DropDownList1.Items.Add("Green")
    DropDownList1.Items.Add("Blue")
End Sub

End Class

1 个答案:

答案 0 :(得分:2)

根据Microsoft的documentation,如果要恢复其值,则在加载ViewState时需要存在动态添加的控件。在ViewStateInitialization阶段之间加载Load

Microsoft建议在PreInit中重新创建它们: enter image description here