技术: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
答案 0 :(得分:2)
根据Microsoft的documentation,如果要恢复其值,则在加载ViewState
时需要存在动态添加的控件。在ViewState
和Initialization
阶段之间加载Load
。
Microsoft建议在PreInit
中重新创建它们: