C# 动态创建的控件在回发后丢失数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17589268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamically Created Controls losing data after postback
提问by RealSteel
Actually, I am Creating 1 TextBoxon Pageloadand adding that TextBoxto Panel.
Now, I have a LinkButtonlike Add Another.
其实,我创建1TextBox上Pageload,并补充说TextBox来Panel。现在,我有一个LinkButton喜欢Add Another。
I am entering Text in that TextBoxand if needed I need to Create New TextBox,by clicking Add Another LinkButton.
我在其中输入 Text ,TextBox如果需要,我需要TextBox通过单击Create New Add Another LinkButton。
Actually, I am able to get the count and recreate the TextBoxes.
But,the Problem is that, My Entered text in the Previously Generated Textboxesis Missing.
实际上,我能够获得计数并重新创建TextBoxes. 但是,问题是,我在先前生成中输入的文本Textboxes丢失了。
Can Anyone,Suggest me a solution for this?
任何人都可以,建议我解决这个问题吗?
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (!IsPostBack)
{
for (int i = 0; i < 5; i++)
{
TableRow row = new TableRow();
for (int j = 0; j < 5; j++)
{
TableCell cell = new TableCell();
TextBox tb = new TextBox();
tb.ID = "TextBoxRow_" + i + "Col_" + j;
cell.Controls.Add(tb);
row.Cells.Add(cell);
}
Table1.Rows.Add(row);
}
}
}
catch (Exception ex)
{
throw;
}
}
This is a Sample Code, the same code is written in Button_ClickAlso
这是一个示例代码,同样的代码写在Button_ClickAlso
protected void ASPxButton1_Click(object sender, EventArgs e)
{
int k = Table1.Controls.Count;
}
I am getting a Count=0on Button_Click.
我得到一个Count=0上Button_Click。
采纳答案by Vivek
All you need to do is to re-instantiate / reinitialize dynamic controls before or within page load event each and every time during postbackand add this control to page / forms / placeholders. Then, the posted data will automatically be assigned to the control by calling the LoadPostData method by the parent control.
您需要做的就是在回发期间每次在页面加载事件之前或之内重新实例化/重新初始化动态控件,并将此控件添加到页面/表单/占位符。然后,通过父控件调用 LoadPostData 方法,将发布的数据自动分配给控件。
check the article and how to write code for dynamic control - How to maintain dynamic control events, data during postback in asp.net
查看文章以及如何编写动态控件的代码 - 如何在asp.net 中回发期间维护动态控件事件、数据


回答by Adil
The dynamically generated control do not maintain state. You have to maintain it at your own. You can use some hidden field to keep the state of controls, which will be used on server side to extract the state. Asp.net uses hidden field to maintain the state between requests, you can see __VIEWSTATEin the source.
动态生成的控件不保持状态。你必须自己维护它。您可以使用一些隐藏字段来保持控件的状态,这些字段将在服务器端用于提取状态。Asp.net 使用隐藏字段来维护请求之间的状态,你可以__VIEWSTATE在源码中看到。
In ASP.NET pages, the view state represents the state of the page when it was last processed on the server. It's used to build a call context and retain values across two successive requests for the same page. By default, the state is persisted on the client using a hidden field added to the page and is restored on the server before the page request is processed. The view state travels back and forth with the page itself, but does not represent or contain any information that's relevant to client-side page display, Reference.
在 ASP.NET 页面中,视图状态表示页面上次在服务器上处理时的状态。它用于构建调用上下文并在同一页面的两个连续请求中保留值。默认情况下,使用添加到页面的隐藏字段将状态保留在客户端上,并在处理页面请求之前在服务器上恢复。视图状态与页面本身一起来回移动,但不表示或包含与客户端页面显示相关的任何信息,参考。
回答by R.C
When using dynamic controls, you must remember that they will exist only until the next postback.ASP.NET will not re-create a dynamically added control. If you need to re-create a control multiple times, you should perform the control creation in the PageLoad event handler ( As currently you are just creating only for first time the TextBox using Condition: !IsPostabck ). This has the additional benefit of allowing you to use view state with your dynamic control. Even though view state is normally restored before the Page.Load event, if you create a control in the handler for the PageLoad event, ASP.NET will apply any view state information that it has after the PageLoad event handler ends.
使用动态控件时,您必须记住它们只会存在到下一次回发。ASP.NET 不会重新创建动态添加的控件。如果您需要多次重新创建控件,您应该在 PageLoad 事件处理程序中执行控件创建(因为目前您只是第一次使用 Condition: !IsPostabck 创建 TextBox)。这有一个额外的好处,即允许您将视图状态与动态控件一起使用。即使视图状态通常在 Page.Load 事件之前恢复,如果在 PageLoad 事件的处理程序中创建控件,ASP.NET 将在 PageLoad 事件处理程序结束后应用它拥有的任何视图状态信息。
So, Remove the Condition: !IsPostback, So that each time the page Loads, The TextBox control is also created. You will also see the State of Text box saved after PageLoad handler completes. [ Obviously you have not disabled ViewState!!! ]
因此,删除条件:!IsPostback,以便每次加载页面时,还会创建 TextBox 控件。您还将看到在 PageLoad 处理程序完成后保存的文本状态框。[显然你没有禁用ViewState!!!]
Example:
例子:
protected void Page_Load(object sender, EventArgs e)
{
TextBox txtBox = new TextBox();
// Assign some text and an ID so you can retrieve it later.
txtBox.ID = "newButton";
PlaceHolder1.Controls.Add(txtBox);
}
Now after running it, type anything in text box and see what happens when you click any button that causes postback. The Text Box still has maintained its State!!!
现在运行它后,在文本框中输入任何内容,看看当您单击任何导致回发的按钮时会发生什么。文本框仍然保持其状态!!!
回答by RealSteel
Actually, I have used Javascript for accomplishing my task. and it goes like this :
实际上,我已经使用 Javascript 来完成我的任务。它是这样的:
<form id="form1" runat="server" enctype="multipart/form-data" method="post">
<span style="font-family: Arial">Click to add files</span>
<input id="Button1" type="button" value="add" onclick="AddFileUpload()" />
<br />
<br />
<div id="FileUploadContainer">
<!--FileUpload Controls will be added here -->
</div>
<asp:HiddenField ID="HdFirst1" runat="server" Value="" />
<br />
<asp:Button ID="btnUpload" runat="server" Text="Upload" OnClick="btnUpload_Click" />
</form>
Script :
脚本 :
<script type="text/javascript">
var counter = 0;
function AddFileUpload() {
var div = document.createElement('DIV');
div.innerHTML = '<input id="file' + counter + '"name = "file' + counter + '"type="text"/><input id="file' + counter + '" name = "file' + counter + '" type="file" /><input id="Button' + counter + '" type="button" value="Remove" onclick = "RemoveFileUpload(this)" />';
document.getElementById("FileUploadContainer").appendChild(div);
counter++;
}
function RemoveFileUpload(div) {
document.getElementById("FileUploadContainer").removeChild(div.parentNode);
}
function mydetails(div) {
var info;
for (var i = 0; i < counter; i++) {
var dd = document.getElementById('file' + i).value;
info = info + "~" + dd;
}
document.getElementById('<%= HdFirst1.ClientID %>').value = info;
}
</script>
and In the Upload_Click Button :
并在 Upload_Click 按钮中:
for (int i = 0; i < Request.Files.Count; i++)
{
string strname = HdFirst1.Value;
string[] txtval = strname.Split('~');
HttpPostedFile PostedFile = Request.Files[i];
if (PostedFile.ContentLength > 0)
{
string FileName = System.IO.Path.GetFileName(PostedFile.FileName);
// string textname=
//PostedFile.SaveAs(Server.MapPath("Files\") + FileName);
}
}
回答by RealSteel
This is My final answer after working a lot with Dynamic Controls
这是我在使用 Dynamic Controls 进行大量工作后的最终答案
.aspx
.aspx
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div style="text-align: center">
<div style="background-color: Aqua; width: 250px;">
<br />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:PlaceHolder runat="server" ID="myPlaceHolder"></asp:PlaceHolder>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnAddTextBox" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<br />
</div>
<br />
<asp:Button ID="btnAddTextBox" runat="server" Text="Add TextBox" OnClick="btnAddTextBox_Click" />
<br /><br />
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<asp:Button runat="server" ID="MyButton" Text="Get Values." OnClick="MyButton_Click" />
<br /><br />
<asp:Label runat="server" ID="MyLabel"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
.aspx.cs
.aspx.cs
static int myCount = 0;
private TextBox[] dynamicTextBoxes;
protected void Page_PreInit(object sender, EventArgs e)
{
Control myControl = GetPostBackControl(this.Page);
if ((myControl != null))
{
if ((myControl.ClientID.ToString() == "btnAddTextBox"))
{
myCount = myCount + 1;
}
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
dynamicTextBoxes = new TextBox[myCount];
int i;
for (i = 0; i < myCount; i += 1)
{
TextBox textBox = new TextBox();
textBox.ID = "myTextBox" + i.ToString();
myPlaceHolder.Controls.Add(textBox);
dynamicTextBoxes[i] = textBox;
LiteralControl literalBreak = new LiteralControl("<br />");
myPlaceHolder.Controls.Add(literalBreak);
}
}
protected void btnAddTextBox_Click(object sender, EventArgs e)
{
// Handled in preInit due to event sequencing.
}
protected void MyButton_Click(object sender, EventArgs e)
{
MyLabel.Text = "";
foreach (TextBox tb in dynamicTextBoxes)
{
MyLabel.Text += tb.Text + " :: ";
}
}
public static Control GetPostBackControl(Page thePage)
{
Control myControl = null;
string ctrlName = thePage.Request.Params.Get("__EVENTTARGET");
if (((ctrlName != null) & (ctrlName != string.Empty)))
{
myControl = thePage.FindControl(ctrlName);
}
else
{
foreach (string Item in thePage.Request.Form)
{
Control c = thePage.FindControl(Item);
if (((c) is System.Web.UI.WebControls.Button))
{
myControl = c;
}
}
}
return myControl;
}
回答by Se?kin Durgay
Just remove this line
只需删除此行
if (!IsPostBack)
回答by Jatin Phulera
When you are working with dynamic controls they will not able to maintain its state during postback and their data lost Cause they dont have any viewstate to maintain their data.
当您使用动态控件时,它们将无法在回发期间保持其状态并且它们的数据丢失,因为它们没有任何视图状态来维护其数据。
You only need to maintain the created controls data into ViewState dynamically and loads the data into page at the time of postback and you done.
您只需要在回发时将创建的控件数据动态维护到 ViewState 中,然后将数据加载到页面中即可。
public Dictionary<Guid, string> UcList
{
get { return ViewState["MyUcIds"] != null ? (Dictionary<Guid, string>)ViewState["MyUcIds"] : new Dictionary<Guid, string>(); }
set { ViewState["MyUcIds"] = value; }
}
public void InitializeUC()
{
int index = 1;
foreach (var item in UcList)
{
var myUc = (UserControls_uc_MyUserControl)LoadControl("~/UserControls/uc_MyUserControl.ascx");
myUc.ID = item.Value;
pnlMyUC.Controls.AddAt(index, myUc);
index++;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadControl();
else
InitializeUC();
}
Here you can find the best understanding about postback and postback for Dynamic controls. Retain dynamic control values in every postback or event click.
在这里您可以找到有关动态控件回发和回发的最佳理解。在每个回发或事件点击中保留动态控制值。

