在用户控件中的数据列表中触发下拉事件时,动态添加的控件将被删除

Aja*_*707 7 vb.net asp.net user-controls datalist dynamic-controls

我正在开发一个ASP.NET VB.NET Web表单 - 一个预订Web应用程序,其中只有一个aspx页面和其余部分是用户控制页面.

在aspx页面的运行时,用户控件按步骤加载,名称在db中定义,如下面的链接.

ASP.NET自定义用户控件动态添加

在第一步中,第一个用户控件是在page-init中绑定,用于显示.NET datalist控件中的预留可用性详细信息(参见图像).

在此输入图像描述

绑定所有细节以通过data-list的item_databound事件生成运行时控件.

  1. ImageOfRoom(asp.net图像控件) - 点击弹出窗口将打开滚动功能
  2. 名称(直接数据绑定)
  3. 设施(图标) - 从db动态添加.
  4. No. of room as per room type (asp.net dropdown control) - dynamically add from db and on selected index changed, need another dropdown bind in same row and on change of adult dropdown price will vary.
  5. Total price (direct databound)
  6. Book now (button)

在此输入图像描述

Now issue is whenever any event of datalist(click on romm-image or dropdown selected index changed) fired, the dynamic control remove like ammenities, dynamic dropdown of other row etc.

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

I checked this also, But no luck. : Dynamically added controls in Asp.Net

I analyze that, the user-control is always rebound and then event fired, but no datalist rebind and thus no - databound event fire and finally dynamic control is removed. If you wish, I will share the code too (but its huge code).

那么问题是如何在下拉选择索引更改或在usercontrol中的datalist中触发图像点击事件时保留动态控件及其值?

我没有使用更新面板,这有用吗?如果是,那么请提供样本数据.

很好地回答样本数据.即使请通过网格视图等任何其他控件建议,如果可能的话,我准备改变它.

更新 这是我的代码

加载用户控制代码 在aspx页面中,usercontrol定义根据当前步骤加载另一个用户控件.这个"uc"用户控件标签在aspx页面中.

<div id="divPlaceholder" runat="server">
        <uc:DynamicControlHost ID="ucDynamicControlHost" runat="server" />
 </div>
Run Code Online (Sandbox Code Playgroud)

在page_load和page_prerender(ispostback)中,下面的代码执行以加载运行时用户控件.

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;
    }
Run Code Online (Sandbox Code Playgroud)

usercontrol中datalist的结构

<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>
Run Code Online (Sandbox Code Playgroud)

Datalist项目数据绑定事件代码(其内部图像绑定,价格相关字段添加并根据条件创建动态控件)

  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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

关于动态生成的下拉选择事件被触发

在上面甚至动态地添加这个下拉列表,现在当调用此控件的事件时,进一步的动态控制正在根据条件添加.

问题是这个事件删除了动态的其他控件,即使前一个选择的其他行被隐藏或丢失,所以我们保留动态控件在任何帖子后退和事件触发.

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 />"));
        }
    }
Run Code Online (Sandbox Code Playgroud)

ibr*_*ity 3

我不确定这能为您解决多少问题,但这是一个在 gridview 中保留一行数据的示例,其中模板字段包含动态生成的下拉列表

我将这个过程分为两部分 1) 将当前 Gridview 中的数据保存到会话变量 2) 重新创建、源代码和绑定控件

这里将值保存在网格视图中。我使用在此站点上找到的递归查找控件公式(但不记得从哪里),因为我的控件是生成并放置在没有唯一名称的 gridview 行内。对于前。第 1 行中存在的 tbxA 与第 2 行中的 tbxA 不同。这可能不适用于您 -关键是找到您想要保存其值的所有控件。

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
Run Code Online (Sandbox Code Playgroud)

然后在 Page_Load 下(当它是回发时)将 gridview 数据源设置为会话变量,并对其进行数据绑定。这将为每一行触发以下代码:请记住,我还将下拉列表的数据源存储在页面加载时的会话变量中。这允许每次生成下拉列表时都会发生数据源和数据绑定。

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
Run Code Online (Sandbox Code Playgroud)

ddlA.SelectedValue = TryCast(e.Row.DataItem, DataRowView).Row.Item("A").ToString()是在任何回发后保留数据的原因。它确定要绑定哪一行,然后用以前的内容重新填充控件。

希望这可以帮助!

要确保每次都会填充 gridview,请在事件处理程序中调用 SaveValues。

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
Run Code Online (Sandbox Code Playgroud)