GThree
GThree

Reputation: 3552

Duplicate columns get created while clicking "Edit" in asp:GridView

I have asp:GridView where I am using AutoGenerateEditButton="True" property to edit the grid row. Now the issue is whenever I click Edit button, the columns are populating again. For example If there 4 columns and if I click Edit than same 4 columns will reappear.

.ASPX Code:

<asp:GridView ID="grdEmpDetail" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" 
            OnRowEditing="grdEmpDetail_RowEditing"
            OnRowCancelingEdit="grdEmpDetail_RowCancelingEdit"
            OnRowUpdated="grdEmpDetail_RowUpdated" 
            AutoGenerateEditButton="True">
</asp:GridView>

Code Behind: To Dynamically bind data on grid

protected void Page_Load(object sender, EventArgs e)
{
    WorkSampleBusiness.BusinessObject objBL = new WorkSampleBusiness.BusinessObject();
    this.grdEmpDetail.AutoGenerateColumns = false;
    try
    {
        DataTable dt = new DataTable();
        dt = objBL.OrderDetail();
        foreach (var col in dt.Columns)
        {
            if (col.ToString() == "ID" || col.ToString() == "First Name" || col.ToString() == "Last Name" || col.ToString() == "Business Phone" || col.ToString() == "Job Title")
            {
                BoundField objBoundField = new BoundField();
                objBoundField.DataField = col.ToString();
                objBoundField.HeaderText = col.ToString();
                this.grdEmpDetail.Columns.Add(objBoundField);
            }
        }
        this.grdEmpDetail.DataSource = dt;
        this.grdEmpDetail.DataBind();
    }
    catch
    {
        throw;
    }
}

Handle Edit Mode:

protected void grdEmpDetail_RowEditing(object sender, GridViewEditEventArgs e)
    {
        this.grdEmpDetail.EditIndex = e.NewEditIndex;
        this.grdEmpDetail.DataBind();
    }

protected void grdEmpDetail_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
    {
        this.grdEmpDetail.EditIndex = -1;
        this.grdEmpDetail.DataBind();
    }

OUTPUT: This is fine

enter image description here

ISSUE : This is where I am getting issue.

enter image description here

What am I missing here?

Upvotes: 0

Views: 620

Answers (2)

A_Sk
A_Sk

Reputation: 4630

Try:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        Fill_Grid();
    }
}
protected Void Fill_Grid()
{

    if (grdEmpDetail.Columns.Count > 0)
    {
        for (int n = 0; n < grdEmpDetail.Columns.Count; n++)
        {
            grdEmpDetail.Columns.RemoveAt(n);

        }
     grdEmpDetail.DataBind();
    }
    this.grdEmpDetail.AutoGenerateColumns = false;
    WorkSampleBusiness.BusinessObject objBL = new WorkSampleBusiness.BusinessObject();
    try
    {
        DataTable dt = new DataTable();
        dt = objBL.OrderDetail();
        foreach (var col in dt.Columns)
        {
            if (col.ToString() == "ID" || col.ToString() == "First Name" || col.ToString() == "Last Name" || col.ToString() == "Business Phone" || col.ToString() == "Job Title")
            {
                BoundField objBoundField = new BoundField();
                objBoundField.DataField = col.ToString();
                objBoundField.HeaderText = col.ToString();
                this.grdEmpDetail.Columns.Add(objBoundField);
            }
        }
        this.grdEmpDetail.DataSource = dt;
        this.grdEmpDetail.DataBind();
    }
    catch (exception e1)
    {
    }
}
protected void grdEmpDetail_RowEditing(object sender, GridViewEditEventArgs e)
{
    this.grdEmpDetail.EditIndex = e.NewEditIndex;
    Fill_Grid();
}

protected void grdEmpDetail_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
    this.grdEmpDetail.EditIndex = -1;
    Fill_Grid();
}

Upvotes: 0

mclark1129
mclark1129

Reputation: 7592

You are not checking for IsPostBack in your databinding code. As a result, each time you post to the page that code is being executed again and again. So each time you will add more columns.

Modify your handler like so:

protected void Page_Load(object sender, EventArgs e)
{
    if(!IsPostBack) {
       // All of your existing code goes here
    }
}

Edit

It's a little more complicated than that. You DO actually need to re-bind your DataGrid to the data source when you click edit, but you just don't want to add the columns again. This requires that you break up your code some so that the code for data-binding can be re-used without being tied to the column addition.

First, let's create a method specifically for adding columns that appear on an input DataTable:

private void AddColumnsToDataGrid(DataTable dt) {

    foreach (var col in dt.Columns) {
        if (col.ToString() == "ID" 
            || col.ToString() == "First Name" 
            || col.ToString() == "Last Name" 
            || col.ToString() == "Business Phone" 
            || col.ToString() == "Job Title")
        {
            BoundField objBoundField = new BoundField();
            objBoundField.DataField = col.ToString();
            objBoundField.HeaderText = col.ToString();
            this.grdEmpDetail.Columns.Add(objBoundField);
        }
    }

}

Next Create a Method for Databinding a DataTable to your grid:

private void DataBindGrid(DataTable dt) {

    this.grdEmpDetail.DataSource = dt;
    this.grdEmpDetail.DataBind();

}

Now that you've extracted some of that code out, you can re-use these methods where appropriate, and only add columns one time:

Page Load Handler

protected void Page_Load(object sender, EventArgs e)
{
    if(!IsPostBack) {

        WorkSampleBusiness.BusinessObject objBL = new WorkSampleBusiness.BusinessObject();
        this.grdEmpDetail.AutoGenerateColumns = false;

        try {
            DataTable dt = objBL.OrderDetail();
            AddColumnsToDataGrid(dt);
            DataBindGrid(dt);
        } catch {
            // Side Note:  If you're just re-throwing the exception
            // then the try/catch block is completely useless.
            throw;
        }

    }

}

Editing Handlers

protected void grdEmpDetail_RowEditing(object sender, GridViewEditEventArgs e)
{

    this.grdEmpDetail.EditIndex = e.NewEditIndex;

    WorkSampleBusiness.BusinessObject objBL = new WorkSampleBusiness.BusinessObject();    
    DataBindGrid(objBL.OrderDetail());

}

protected void grdEmpDetail_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
    this.grdEmpDetail.EditIndex = -1;

    WorkSampleBusiness.BusinessObject objBL = new WorkSampleBusiness.BusinessObject();    
    DataBindGrid(objBL.OrderDetail());

}

Upvotes: 1

Related Questions