Динамически созданные элементы управления, теряющие данные после обратной передачи
На самом деле, я создаю 1 TextBox
на Pageload
и добавив, что TextBox
в Panel
, Теперь у меня есть LinkButton
лайк Add Another
,
Я ввожу текст в этом TextBox
и при необходимости мне нужно создать новый TextBox
,кликнув Add Another LinkButton
,
На самом деле, я могу получить счет и воссоздать TextBoxes
, Но проблема в том, что мой введенный текст в ранее сгенерированном Textboxes
пропал, отсутствует.
Может ли кто-нибудь, предложить мне решение для этого?
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;
}
}
Это пример кода, тот же код написан на Button_Click
Также
protected void ASPxButton1_Click(object sender, EventArgs e)
{
int k = Table1.Controls.Count;
}
Я получаю Count=0
на Button_Click
,
7 ответов
Это мой окончательный ответ после много работы с Dynamic Controls
.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
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;
}
Все, что вам нужно сделать, - это повторно создавать / повторно инициализировать динамические элементы управления до или внутри события загрузки страницы каждый раз во время обратной передачи и добавлять этот элемент управления в страницу / формы / заполнители. Затем опубликованные данные будут автоматически назначены элементу управления путем вызова метода LoadPostData родительским элементом управления.
проверить статью и как написать код для динамического управления - Как поддерживать динамические события управления, данные во время обратной передачи в asp.net
При использовании динамических элементов управления вы должны помнить, что они будут существовать только до следующего постбэка.ASP.NET не создаст заново динамически добавленный элемент управления. Если вам нужно повторно создать элемент управления несколько раз, вы должны выполнить создание элемента управления в обработчике событий PageLoad (поскольку в настоящее время вы просто создаете только первый раз TextBox, используя Condition:!IsPostabck). Это дает дополнительное преимущество, позволяя вам использовать состояние просмотра с вашим динамическим управлением. Даже если состояние представления обычно восстанавливается до события Page.Load, если вы создадите элемент управления в обработчике для события PageLoad, ASP.NET применит любую информацию о состоянии представления, которая у него есть, после завершения обработчика события PageLoad.
Итак, удалите условие:!IsPostback, чтобы при каждой загрузке страницы также создавался элемент управления TextBox. Вы также увидите поле состояния текста, сохраненное после завершения обработчика PageLoad. [Очевидно, вы не отключили ViewState!!! ]
Пример:
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);
}
Теперь после запуска введите что-нибудь в текстовое поле и посмотрите, что произойдет, если вы нажмете любую кнопку, которая вызывает обратную передачу. Текстовое поле все еще сохранило свое состояние!!!
Динамически генерируемый элемент управления не поддерживает состояние. Вы должны поддерживать это по своему усмотрению. Вы можете использовать некоторые скрытые поля для сохранения состояния элементов управления, которые будут использоваться на стороне сервера для извлечения состояния. Asp.net использует скрытое поле для поддержания состояния между запросами, вы можете увидеть __VIEWSTATE
в источнике.
На страницах ASP.NET состояние просмотра представляет состояние страницы, когда она последний раз обрабатывалась на сервере. Он используется для построения контекста вызова и сохранения значений в двух последовательных запросах на одну и ту же страницу. По умолчанию состояние сохраняется на клиенте с использованием скрытого поля, добавленного на страницу, и восстанавливается на сервере до обработки запроса страницы. Состояние просмотра перемещается назад и вперед вместе с самой страницей, но не представляет и не содержит никакой информации, относящейся к отображению страницы на стороне клиента, " Ссылка".
Когда вы работаете с динамическими элементами управления, они не смогут поддерживать его состояние во время обратной передачи, и их данные будут потеряны. Потому что у них нет никакого состояния, чтобы поддерживать свои данные.
Вам нужно только динамически поддерживать созданные данные управления во 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();
}
Здесь вы можете найти лучшее понимание обратной передачи и обратной передачи для динамических элементов управления. Сохраняйте значения динамического контроля в каждом постбэке или щелчке по событию.
На самом деле, я использовал 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 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>
и в кнопке 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);
}
}