Anurag
Anurag

Reputation: 572

Dropdownlist selection doesn't persist data on AddRow button click

I have an editable GridView.

I have an AddRow button, which adds a row which consists of 3 text boxes and one dropdown list.

Also, I have a Delete button, which removes the whole row when clicked.

Whenever I click on AddRow button, the selection of my dropdownlist doesn't persist, the selected value is realigned to the very first item.

Below are the codes:

<asp:GridView ID="GridView1" runat="server" ShowFooter="true" AutoGenerateColumns="false"
            OnRowDeleting="GridView1_RowDeleting">
            <Columns>
                <asp:TemplateField HeaderText="Serial No">
                    <ItemTemplate>
                        <asp:Label ID="Label1" runat="server" Text='<%# Container.DataItemIndex + 1 %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Col1">
                    <ItemTemplate>
                        <asp:TextBox runat="server" ID="txt1" Text='<%# Eval("Column1") %>'></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Col2">
                    <ItemTemplate>
                        <asp:TextBox ID="txt2" runat="server" Text='<%# Eval("Column2") %>'></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Col3">
                    <ItemTemplate>
                        <asp:TextBox ID="txt3" runat="server" Text='<%# Eval("Column3") %>'></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="DropDown">
                    <ItemTemplate>
                        <asp:DropDownList ID="DropDownList1" runat="server" DataTextField='<%# Eval("Column4") %>'>
                            <asp:ListItem>London</asp:ListItem>
                            <asp:ListItem>Paris</asp:ListItem>
                            <asp:ListItem>New Delhi</asp:ListItem>
                            <asp:ListItem>New York</asp:ListItem>
                        </asp:DropDownList>
                    </ItemTemplate>
                    <FooterStyle HorizontalAlign="Right" />
                    <FooterTemplate>
                        <asp:Button ID="btnAddNewRow" runat="server" Text="AddRow" OnClick="Add" />
                    </FooterTemplate>
                </asp:TemplateField>
                <asp:CommandField ButtonType="Button" ShowDeleteButton="true" />
            </Columns>
        </asp:GridView>
        <asp:Button ID="btnSavetoDB" runat="server" Text="save" OnClick="btnSavetoDB_Click" />

EDITED CODE:

     List<string> newList = new List<string>();
     protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                var table = CreateDataTable();
                table.Rows.Add("", "", "");
                BindGridView(table);
            }
        }
    //Called on AddRow button click
    protected void Add(object sender, EventArgs e)
            {
                var newTable = PopulateTableFromGridView();
                newTable.Rows.Add("", "", "");
                BindGridView(newTable);
             }
    private DataTable PopulateTableFromGridView()
        {
            var table = CreateDataTable();
            for (int i = 0; i < GridView1.Rows.Count; i++)
            {
                //extract the TextBox values
                TextBox box1 = (TextBox)GridView1.Rows[i].FindControl("txt1");
                TextBox box2 = (TextBox)GridView1.Rows[i].FindControl("txt2");
                TextBox box3 = (TextBox)GridView1.Rows[i].FindControl("txt3");
                DropDownList ddl = (DropDownList)GridView1.Rows[i].FindControl("DropDownList1");
                table.Rows.Add(box1.Text, box2.Text, box3.Text,ddl.SelectedItem.Text);
            }
            newList.Add(ddl.SelectedItem.Text);//add selecteditems to a global list
            return table;
        }
        //Sets the first empty row to the grid view
        private DataTable CreateDataTable()
        {
            var dt = new DataTable
            {
                Columns = { "Column1", "Column2", "Column3","Column4" }
            };
            return dt;
        }

        private void BindGridView(DataTable table)
        {
            GridView1.DataSource = table;
            GridView1.DataBind();
            for(int i=0;i<GridView1.Rows.Count-1;i++)
            {
                    DropDownList ddl2=(DropDownList)GridView1.Rows[i].FindControl("DropDownList1");
                    ddl2.ClearSelection();
                    ddl2.Items.FindByText(newList[i]).Selected = true;     
            }
        }
         protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
        {
            var dt = PopulateTableFromGridView();
            if (dt.Rows.Count > 1)
            {
                dt.Rows[e.RowIndex].Delete();
            }
            BindGridView(dt);
        }

The first screenshot, I have selected NewDelhi from the dropdownlist, which is the 3rd item:

enter image description here

The second screenshot, wherein a new row has been added after AddRow button is clicked, the dropdownlist is realigned in the first row, shows London.

enter image description here

How to make the code persist the dropdownlist selection when AddRow and Delete button is clicked?

I tried disabling the AutoPostBack property of the dropdownlist to false, but to no effect. Experts please help.

SUCCESSFUL SCREENSHOTS: enter image description here

enter image description here

Upvotes: 0

Views: 420

Answers (2)

Anurag
Anurag

Reputation: 572

I have solved the problem after some R&D.

I have created a new instance of dropdownlist after the gridview is bound, and in that new instance, I am preserving the previous selection using a List from the PopulateGridView method.

Please see the edit of the code.

Hope this helps some body.

Upvotes: 1

fnostro
fnostro

Reputation: 4591

Every time you hit the addrow button you are performing a postback.

every postback rebuilds then entire page including the grid based on your table. You can see that in your own code.

But part of this is that the controls within each row are rebuilt too. This includes your DDL's, but you are not saving/restoring the selected values from each drop down. More correctly, the selected values are saved but are invalidated when you recreate the table. you have to handle the RowDatabound event and in each row restore the selected value in the ddl.

But you may have a bigger problem. You are using the same instance of the DDL in each row. this may cause selection/persistence issues. If you find that selecting an item from the ddl causes all rows to have the same selected item, that's the problem in action.

Take a look at the rendered output for your ddl's and make sure the id's are unique for each row.

if the ddl has it's own datasource then you need to create a new instance of a DropDownlist in each row and assign it the same datasource rather than using find control.

if the control has it's list items hard coded then you should just check for unique ddl id's

Upvotes: 0

Related Questions