당신은 당신이 무엇을 필요 최소한을 저장할 수 세션에서 개최되는 콜렉션에서 컨트롤을 재현하는 방법을 알고 있어야합니다. 세션은 페이지의 초기화 단계에서 사용할 수 있습니다.
다음은 당신을위한 예입니다. 그것은 구성
이
Default.aspx를, CS
이 - 사용자를 저장하는 패널 제어
- 그것은
TimeTeller.ascx, CS
를 클릭 할 때마다 사용자 컨트롤을 추가 할 것이다 "제어 버튼 추가" - 컨트롤의 레이블을 지정된 시간으로 설정하는 SetTime이라는 메서드가 있습니다.
Default.aspx를
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DynamicControlTest._Default" %>
<!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">
<div>
<asp:Panel ID="pnlDynamicControls" runat="server">
</asp:Panel>
<br />
<asp:Button ID="btnAddControl" runat="server" Text="Add User Control"
onclick="btnAddControl_Click" />
</div>
</form>
</body>
</html>
하여 default.aspx.cs :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace DynamicControlTest
{
public partial class _Default : System.Web.UI.Page
{
Dictionary<string, string> myControlList; // ID, Control ascx path
protected void Page_Load(object sender, EventArgs e)
{
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (!IsPostBack)
{
myControlList = new Dictionary<string, string>();
Session["myControlList"] = myControlList;
}
else
{
myControlList = (Dictionary<string, string>)Session["myControlList"];
foreach (var registeredControlID in myControlList.Keys)
{
UserControl controlToAdd = new UserControl();
controlToAdd = (UserControl)controlToAdd.LoadControl(myControlList[registeredControlID]);
controlToAdd.ID = registeredControlID;
pnlDynamicControls.Controls.Add(controlToAdd);
}
}
}
protected void btnAddControl_Click(object sender, EventArgs e)
{
UserControl controlToAdd = new UserControl();
controlToAdd = (UserControl)controlToAdd.LoadControl("TimeTeller.ascx");
// Set a value to prove viewstate is working
((TimeTeller)controlToAdd).SetTime(DateTime.Now);
controlToAdd.ID = Guid.NewGuid().ToString(); // does not have to be a guid, just something unique to avoid name collision.
pnlDynamicControls.Controls.Add(controlToAdd);
myControlList.Add(controlToAdd.ID, controlToAdd.AppRelativeVirtualPath);
}
}
}
TimeTeller.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TimeTeller.ascx.cs" Inherits="DynamicControlTest.TimeTeller" %>
<asp:Label ID="lblTime" runat="server"/>
TimeTeller.ascx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace DynamicControlTest
{
public partial class TimeTeller : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public void SetTime(DateTime time)
{
lblTime.Text = time.ToString();
}
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
lblTime.Text = (string)ViewState["lblTime"];
}
protected override object SaveViewState()
{
ViewState["lblTime"] = lblTime.Text;
return base.SaveViewState();
}
}
}
당신이 볼 수 있듯이 여전히 내 사용자 정의 컨트롤의 내부 viewstate를 관리해야하지만 viewstate 가방은 페이지에 저장되고 포스트 백 컨트롤에 다시 전달됩니다. 내 해결책은 데이비드와 아주 가깝다는 것을 알아 두는 것이 중요하다고 생각합니다. 내 예제의 유일한 주요 차이점은 viewstate 대신 세션을 사용하여 제어 정보를 저장한다는 점입니다. 이것은 초기화 단계에서 일어날 수 있습니다. 이 솔루션은 더 많은 서버 리소스를 차지하므로 확장 전략에 따라 상황에 따라 적절하지 않을 수 있습니다.
조금 늦었지만 다음과 같이합니다. http://stackoverflow.com/a/15346332/52898 – Tommy