Dynamically added controls are deleted when a drop-down event is fired in a datalist in user control

I am working on an ASP.NET VB.NET web form, a web-based backup application in which there is only one aspx page and the rest of the user management pages.

At runtime of an aspx page, user controls load by step and name in db, as shown below.

ASP.NET Custom User Control for Dynamic Addition

At the first stage, the first user control is the binding in page-init, which is used to display the details of the availability of the reservation in the .NET datalist control, for example (see images).

enter image description here

All details are linked to generate runtime control through the item_databound event data.

  • ImageOfRoom (asp.net Image Control) - a popup window opens with a scroll function
  • Name (direct data binding)
  • Amenities (icon (s)) - dynamically add from db.
  • Not. rooms depending on the type of room (asp.net drop-down control) - dynamically add from db and changed according to the selected index, you need another link in the same line and when the price of the drop-down adult changes, it will change.
  • Total price (direct reference)
  • Book (button)

enter image description here

Now every time a datalist event is fired (clicking on a playlist of a romm image or a drop-down list), the dynamic control is deleted as ammenities, the dynamic drop-down menu of another line, etc.

What I tried as: - ispostback, relevant page life cycle event, ajax-jquery, viewstate.

I checked it too, but no luck .: Dynamically added controls in Asp.Net

I analyze that the user control is always restored, and then the event is fired, but the data re-binding is not restored, and thus, there is no emergency event and, finally, dynamic control. If you wish, I will also share the code (but its huge code).

So, the question is how to save the dynamic controls and its value if the selected drop-down list index has been changed or the image click event fired in the datalist in usercontrol?

I do not use the update panel, does it work? If so, please provide sample data.

Good answer to sample data. Even please, suppose that, if possible, using any other control, such as grid-view or another, then I am ready to change it.

Update This is my code

Download user control code On the aspx page, usercontrol determines the loading of another user control in accordance with the current step. This custom uc tag is on an aspx page.

<div id="divPlaceholder" runat="server"> <uc:DynamicControlHost ID="ucDynamicControlHost" runat="server" /> </div> 

In page_load, as well as page_prerender (ispostback), the code below is executed to load user runtime control.

 public Control SetUserControlPath(string path) { Control c = null; if (this.dynamicAllContent.Controls.Count > 0) { //Check that the new control is not the same as the current control if (!this.UserControlPath.Equals(path)) { //Remove the old item because we can not simply replace them! this.dynamicPHAllContent.Controls.Clear(); c = Page.LoadControl(path + ".ascx"); c.ID = path; //Add New Item this.dynamicAllContent.Controls.Add(c); lock (_userControlLockObject) { //Store the new path _strUserControl = path; } } } else { c = Page.LoadControl(path + ".ascx"); c.ID = path; this.dynamicAllContent.Controls.Add(c); _strUserControl = path; } return c; } 

Datalist structure in usercontrol

 <asp:UpdatePanel ID="EmployeesUpdatePanel" runat="server" UpdateMode="Conditional"> <ContentTemplate> <asp:DataList ID="dlLodgingAvailableDetails" ShowHeader="true" OnSelectedIndexChanged="dlLodgingAvailableDetails_SelectedIndexChanged" runat="server" CellPadding="2" CellSpacing="2" BorderWidth="1px" BorderColor="Black" OnItemDataBound="dlLodgingAvailableDetails_ItemDataBound" BorderStyle="Solid" GridLines="Horizontal" HorizontalAlign="Justify"> <HeaderStyle CssClass="submit_butt"></HeaderStyle> <HeaderTemplate> Lodging Item Type Details &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <asp:Button ID="btnBookRoom" runat="server" Text="Book Rooms" CssClass="submit_butt" OnClick="btnBookRoom_Click" /> </HeaderTemplate> <ItemTemplate> <table cellpadding="2" cellspacing="0" border="1" style="width: 100%";> <tr> <td style="width:170px"> <asp:ImageButton ID="imgLodging" OnClick="imgLodging_Click" commandargument='<%# Eval("ItemTypeId") %>' runat="server" ImageUrl='<%# Eval("Photo") %>' Width="150px" Height="120px" /> </td> <td style="width:180px"> <b>Name</b><br /> <span><%# Eval("ItemTypeName") %></span><br /> <b>Occupancy</b>&nbsp;<span><%# Eval("Occupancy") %></span> <br />&nbsp; <asp:panel ID="placeholderAmmenities" runat="server" Visible="True" ></asp:panel> </td> <td style="width:100px"> <b>Room</b><br /> <asp:hiddenfield runat="server" ID="hdnItemTypeId" Value='<%# Eval("LodgingItemTypeId") %>' /> <asp:DropDownList ID="ddlAvailable" runat="server" AppendDataBoundItems="True" SelectedValue='<%# Bind("LodgingReservationsAvailable") %>' > <asp:ListItem Value="0" Text="0"/> <asp:ListItem Value="1" Text="1"/> <asp:ListItem Value="2" Text="2"/> </asp:DropDownList> </td> <td> </td> <td style="width:100px"> <div id="dvadult" runat="server"></div> <asp:placeholder runat="server" ID="PlaceHolderAdult" ViewStateMode="Enabled" EnableTheming="False" Visible="True" ></asp:placeholder> </td> <td style="width:50px"> <asp:Label runat="server" ID="lblnumbernight" ></asp:Label> </td> <td style="width:50px"> <asp:placeholder ID="placeholderPrice" runat="server" Visible="True"></asp:placeholder> </td> <td style="width:50px"> <b>Total</b><br /> <asp:Label runat="server" ID="lblTotalAmount" ></asp:Label> </td> <td style="width:100px"> <asp:Button ID="btnBookRoom" runat="server" Text="Book Rooms" CssClass="submit_butt" /> </td> </tr> </table> </ItemTemplate> <SeparatorStyle BackColor="Lime" Font-Bold="False" Font-Italic="False" Font-Overline="False" Font-Strikeout="False" Font-Underline="False" HorizontalAlign="Center" /> </asp:DataList> </ContentTemplate> </asp:UpdatePanel> 

An event code attached to data about data details (its internal binding to the image, the price-related field adds, and also creates dynamic control in accordance with the condition)

  protected void dlLodgingAvailableDetails_ItemDataBound(object sender, DataListItemEventArgs e) { try { if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) { Image img = e.Item.FindControl("imgLodging") as Image; if (img != null) { string bytesval = ((System.Data.DataRowView)(e.Item.DataItem)).Row.ItemArray[3].ToString(); if (string.IsNullOrWhiteSpace(bytesval)) return; byte[] bytes = (byte[])((System.Data.DataRowView)(e.Item.DataItem)).Row.ItemArray[3]; string base64String = Convert.ToBase64String(bytes, 0, bytes.Length); img.ImageUrl = "data:image/png;base64," + base64String; } DropDownList ddlList = e.Item.FindControl("ddlAvailable") as DropDownList; Label lbldipositamount = e.Item.FindControl("lblTotalAmount") as Label; Label lblnumbernight = e.Item.FindControl("lblnumbernight") as Label; var PlaceHolderAmmenities = e.Item.FindControl("placeholderAmmenities") as Panel; ddlList.Attributes.Add("onchange", " openLodgingNumber1(this,'" + ddlList.SelectedValue + "');"); int? LodgingItemTypeId = Convert.ToInt32(((System.Data.DataRowView)(e.Item.DataItem)).Row.ItemArray[1]); DataSet ds = new DataSet(); ds = LodgingData.SelectLodgingItemTypeAmenityDateSet(LodgingItemTypeId); DataTable dt = new DataTable(); if (ds != null) { dt = ds.Tables[0]; if (dt.Rows.Count > 0) { for (int j = 0; j < dt.Rows.Count; j++) { Image image = new Image(); image.ID = "imgAmmenities" + j + DateTime.Now.ToString(); string bytesval = dt.Rows[j]["AmenityIcon"].ToString(); //((System.Data.DataRowView)(e.Item.DataItem)).Row.ItemArray[4].ToStrin(); //if (string.IsNullOrWhiteSpace(bytesval)) return; if (bytesval != string.Empty) { byte[] bytes = (byte[])dt.Rows[j]["AmenityIcon"]; string base64String = Convert.ToBase64String(bytes, 0, bytes.Length); image.ImageUrl = "data:image/png;base64," + base64String; image.Height = 20; image.Width = 20; image.EnableViewState = true; PlaceHolderAmmenities.Controls.Add(image); PlaceHolderAmmenities.Controls.Add(new LiteralControl("&nbsp;")); } } } } decimal PriceTotal = 0; var PlaceHolderPrice = e.Item.FindControl("placeholderPrice") as PlaceHolder; DataSet dsprice = new DataSet(); dsprice = LodgingData.SelectLodgingItemTypePrice(LodgingItemTypeId); if (dsprice != null) { DataTable dtprice = new DataTable(); dtprice = dsprice.Tables[0]; if (dtprice.Rows.Count > 0) { DateTime fromdate = Convert.ToDateTime(txtFromDate.Text); DateTime todate = Convert.ToDateTime(txtToDate.Text); double daterange = ((todate - fromdate).TotalDays + 1); lblnumbernight.Text = daterange.ToString(); //for (DateTime date = fromdate; date >= todate; date.AddDays(1)) for (int d = 0; d < Convert.ToInt32(daterange); d++ ) { DateTime date = fromdate.AddDays(d); //DataView dv = new DataView(dtprice); DataTable dtprice1 = new DataTable(); DataRow[] rows = dtprice.Select("#" + date + "# >= PriceStartDate AND" + "#" + date + "# <= PriceEndDate"); if (rows.Length > 0) { dtprice1 = rows.CopyToDataTable(); } if (dtprice1.Rows.Count > 0) { for (int j = 0; j < dtprice1.Rows.Count; j++) { Label lbl = new Label(); string dayofweek = dtprice1.Rows[j]["DayOfWeekId"].ToString(); if (dayofweek.Trim() == eDayOfWeek.All.ToString().Trim()) { lbl.ID = "lbl" + j; lbl.Text = dtprice1.Rows[j]["Price"].ToString(); PriceTotal += Convert.ToDecimal(dtprice1.Rows[j]["Price"]); PlaceHolderPrice.Controls.Add(lbl); PlaceHolderPrice.Controls.Add(new LiteralControl("<br />")); } else if (Convert.ToInt32(dayofweek) == Convert.ToInt32(date.DayOfWeek + 1)) { lbl.ID = "lbl" + j; lbl.Text = dtprice1.Rows[j]["Price"].ToString(); PriceTotal += Convert.ToDecimal(dtprice1.Rows[j]["Price"]); PlaceHolderPrice.Controls.Add(lbl); PlaceHolderPrice.Controls.Add(new LiteralControl("<br />")); } } } else { DataView dv1 = new DataView(dtprice); dv1.RowFilter = "PriceStartDate IS NULL OR PriceEndDate IS NULL"; //dv1.RowFilter = "PriceStartDate == null and PriceEndDate == null"; DataTable dtprice2 = new DataTable(); dtprice2 = dv1.ToTable(); for (int j = 0; j < dtprice2.Rows.Count; j++) { Label lbl = new Label(); string dayofweek = dtprice2.Rows[j]["DayOfWeekId"].ToString(); if (dayofweek.Trim() == eDayOfWeek.All.ToString().Trim()) { lbl.ID = "lbl" + j; lbl.Text = dtprice2.Rows[j]["Price"].ToString(); PriceTotal += Convert.ToDecimal(dtprice2.Rows[j]["Price"]); PlaceHolderPrice.Controls.Add(lbl); PlaceHolderPrice.Controls.Add(new LiteralControl("<br />")); } else if (Convert.ToInt32(dayofweek) == Convert.ToInt32(date.DayOfWeek + 1)) { lbl.ID = "lbl" + j; lbl.Text = dtprice2.Rows[j]["Price"].ToString(); PriceTotal += Convert.ToDecimal(dtprice2.Rows[j]["Price"]); PlaceHolderPrice.Controls.Add(lbl); PlaceHolderPrice.Controls.Add(new LiteralControl("<br />")); } } } } } } lbldipositamount.Text = PriceTotal.ToString(); // var amount = ((System.Data.DataRowView)(e.Item.DataItem)).Row.ItemArray[3]; int selectedvalue = Convert.ToInt32(ddlList.SelectedItem.Text); if (selectedvalue != 0) { double totalamount = selectedvalue * Convert.ToDouble(PriceTotal); lbldipositamount.Text = totalamount.ToString(); } } } catch (Exception) { throw; } } 

In a dynamically generated dropdown menu selection event

In the above example, dynamically adding this drop-down list, now when this control event is fired, additional dynamic control is added according to the condition.

The problem is that this event deletes a dynamic other control, even if the other line of the previous selection is hidden or lost, therefore we retain dynamic control in any message and fire events.

 protected void ddlAvailable_SelectedIndexChanged(object sender, EventArgs e) { // if (UserControlTextBoxChanged != null) dlLodgingAvailableDetails_ItemDataBound(sender, e); //dlLodgingAvailableDetails.ItemDataBound += new DataListItemEventHandler(dlLodgingAvailableDetails_ItemDataBound); double amount = 0; var ddlList = (DropDownList)sender; var row = (DataListItem)ddlList.NamingContainer; //get the Id of the row DataSet ds = new DataSet(); int? Id = Convert.ToInt32(((HiddenField)row.FindControl("hdnItemTypeId")).Value); double? tamount = Convert.ToDouble(((Label)row.FindControl("lblTotalAmount")).Text); int? groupid = Convert.ToInt32(ddlLodgingGroup.SelectedValue); int selectedvalue = Convert.ToInt32(ddlList.SelectedItem.Text); DateTime? startdate = Convert.ToDateTime(txtFromDate.Text); DateTime? enddate = Convert.ToDateTime(txtToDate.Text); ds = LodgingData.SelectLodgingItemTypeDataSet(startdate, enddate, groupid); DataTable dt = new DataTable(); DataView dv = new DataView(); if (ds != null) { dt = ds.Tables[0]; dv = dt.DefaultView; dv.RowFilter = "LodgingItemTypeId=" + Id; } dt = dv.ToTable(); if (dt.Rows.Count > 0) { if (tamount != null) { amount = Convert.ToDouble(tamount); } } //amount = Convert.ToDouble(((Label)row.FindControl("lblTotalAmount")).Text); var PlaceHolder1 = ((PlaceHolder)row.FindControl("PlaceHolderAdult")); double totalamount = 0; if (selectedvalue != 0) { totalamount = selectedvalue * Convert.ToDouble(amount); ((Label)row.FindControl("lblTotalAmount")).Text = totalamount.ToString(); Label lblAdult = new Label(); lblAdult.ID = "lblAdult"; lblAdult.Text = "Adult"; lblAdult.Font.Bold = true; PlaceHolder1.Controls.Add(lblAdult); PlaceHolder1.Controls.Add(new LiteralControl("<br />")); } else { totalamount = amount; } for (int j = 0; j < selectedvalue; j++) { DropDownList ComboBox = new DropDownList(); ComboBox.ID = "ComboBox" + j; ComboBox.AutoPostBack = false; ComboBox.Attributes.Add("runat", "server"); ComboBox.Items.Add(new ListItem("0", "0")); ComboBox.Items.Add(new ListItem("1", "1")); ComboBox.Items.Add(new ListItem("2", "2")); ComboBox.SelectedIndexChanged += new EventHandler(Dynamic_Method); PlaceHolder1.Controls.Add(ComboBox); PlaceHolder1.Controls.Add(new LiteralControl("<br />")); } } 
+7
user-controls datalist
source share
3 answers

I'm not sure how much this will solve for you, but here is an example of saving a data row in gridview with a template field containing a dynamically generated dropdownlist

I divided the process into 2 parts 1) Save the data in the Gridview in a session variable 2) Recreating, source and binding controls

This is where the values ​​are saved in gridview. I use the recursive search formula that I found on this site (but don’t remember where), because my controls are generated and placed inside the gridview row without unique names. E.g. tbxA, which exists on line 1, is different from tbxA on line 2. This may not apply to you - the key is to find all the controls you want to keep.

 Private Sub SaveValues() Dim savedTable As New DataTable savedTable.Columns.Add(New DataColumn("A")) For i = 0 To GridView1.Rows.Count - 1 Dim existing(0) As Object existing(0) = TryCast(FindControlRecursive(GridView1.Rows(i), "ddlA"), DropDownList).SelectedValue savedTable.Rows.Add(existing) Next Session("GhostTable") = savedTable End Sub 

Then in Page_Load in (when it is a postback) it sets the gridview data source for the session variable and binds it to it. This will call the following code for each line: Keep in mind that I also have a dropdown list data source that is stored in the session variable when the page loads. This allows you to create a data source and data binding for the drop-down list every time it is generated.

 Protected Sub OnRowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound 'Handles databinding of each gridview1 row ddl to gridview templatefield If e.Row.RowType = DataControlRowType.DataRow Then Dim ddlA As New DropDownList() ddlA.DataSource = Session("lengthList") ddlA.DataBind() ddlA.ID = "ddlA" ddlA.SelectedValue = TryCast(e.Row.DataItem, DataRowView).Row.Item("A").ToString() e.Row.Cells(1).Controls.Add(ddlA) End if End Sub 

ddlA.SelectedValue = TryCast(e.Row.DataItem, DataRowView).Row.Item("A").ToString() is what saves data after any postback. It determines which row is bound, and then refills the control with what it once was.

Hope this helps!

To ensure that the gridview is populated each time, call SaveValues ​​in the event handlers.

 Protected Sub ddlEmpNumber_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ddlEmpNumber.SelectedIndexChanged 'Do whatever on selected index change, then the following: Call SaveValues() GridView1.DataSource = Session("GhostTable") GridView1.DataBind() End Sub 
+3
source share

Do it all in the page_init file

You hook up the event handler in the ASP part as follows:

 <asp:DataList ID ... OnSelectedIndexChanged="dlLodgingAvailableDetails_SelectedIndexChanged" ... 

and then in the code of the handler trying to reconnect others:

 ComboBox.SelectedIndexChanged += new EventHandler(Dynamic_Method); 

At any time when you are doing dynamic materials on a web forms page, the entire setup, including posting an event handler, should be in page_init. When events trigger, re-posting will not work. For what you do (asp: ... and during method invocation), this ends up in the wrong part of the life cycle, and the right things don't exist to either add javascript to call doPostback, or if __eventargs does this, etc. d. there is data for controls that are not yet built (postbacks are checked for the AFTER page init function, so you need to create controls before this check) and, therefore, ignore it.

Note. You may know this, but you need to provide unique identifiers for the control, as a rule, this can be done if you have a numeric primary key by simply adding to the datarows. (perhaps this needs to be done manually for child controls in the user control, I had to do it with usercontrols in page_init, I hope you do not)

I am working on a large application that dynamically creates every screen in web forms (from a user interface generator) in an init page. All work is done in events, they work like a charm! Page_load is mostly empty. Get to know the asp page life cycle - it's a booger, but easier than rewriting an application in HotTowel (although think about this next application;)

Pretty good chart: http://blogs.msdn.com/b/aspnetue/archive/2010/01/14/asp-net-page-life-cycle-diagram.aspx

Good luck

+3
source share

I did everything suggested above on another Google search site. But it updates the data and every time restores all dynamic objects in the grid.

Finally, I did everything based on javascript and jquery, without this dynamic control, always double-check what I don't want. Therefore, any body stuck in this situation forgot r and d and worked with javascript / webmethod with dynamic controls.

Thanks to everyone who answered

0
source share

All Articles