动态加载的 UserControl 加载 DropDownList 项目一旦在 PostBack 上消失
Dynamically Loaded UserControl Loading DropDownList Items Once Disappear on PostBack
技术:Asp.Net4.5
我有一个项目可能会加载数百个不同的动态用户控件。当然一次一个,这取决于用户的选择。用户控件界面将在加载时从数据库中填充。
当使用下拉列表动态加载用户控件时,我只想加载一次项目。但是,这些项目在回发时消失了。我在用户控件中使用 Page_Load 来填充下拉列表。我也尝试过 OnInit。到目前为止我尝试过的任何东西似乎都不起作用。
奇怪的是,如果我从主页调用 usercontrol 中的方法,那么每次回发时项目都会保留,而不必每次都重新填充项目。
我希望在添加用户控件时加载一次项目。这是示例代码(非常简单)
主页 - 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>
主页 - 代码隐藏
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
EDIT - 这根据 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
用户控件 - 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>
用户控件 - 代码隐藏
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
根据 Microsoft 的 documentation,如果您想要恢复它们的值,您动态添加的控件将需要在 ViewState
加载时存在。从 ViewState
加载发生在 Initialization
和 Load
阶段之间。
Microsoft 建议在 PreInit
中重新创建它们:
技术:Asp.Net4.5
我有一个项目可能会加载数百个不同的动态用户控件。当然一次一个,这取决于用户的选择。用户控件界面将在加载时从数据库中填充。
当使用下拉列表动态加载用户控件时,我只想加载一次项目。但是,这些项目在回发时消失了。我在用户控件中使用 Page_Load 来填充下拉列表。我也尝试过 OnInit。到目前为止我尝试过的任何东西似乎都不起作用。
奇怪的是,如果我从主页调用 usercontrol 中的方法,那么每次回发时项目都会保留,而不必每次都重新填充项目。
我希望在添加用户控件时加载一次项目。这是示例代码(非常简单)
主页 - 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>
主页 - 代码隐藏
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
EDIT - 这根据 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
用户控件 - 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>
用户控件 - 代码隐藏
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
根据 Microsoft 的 documentation,如果您想要恢复它们的值,您动态添加的控件将需要在 ViewState
加载时存在。从 ViewState
加载发生在 Initialization
和 Load
阶段之间。
Microsoft 建议在 PreInit
中重新创建它们: