Search code examples
c#gridviewasp-classicrowdatabound

asp Gridview column becomes not editable after changing the text in OnRowDataBound event


I use a GridView to display and allow for modifying data. But instead of directly using the data in the database, I have to convert them (consider switching between different date formats), so in the RowDataBound event I update the Text field of one column. However, that data column becomes not editable afterwards when OnRowEditing event is caught.

Code:

    public void OnRowEditing(Object sender, GridViewEditEventArgs e)
    {
        gv.DataSource = getGridViewDataSource();
        gv.EditIndex = e.NewEditIndex;
        gv.DataBind();
    }

    public void OnRowDataBound(Object sender, GridViewRowEventArgs e)
    {
        // convert time display to another format
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            // If I comment out this line, then the field is editable, 
            // but the data format is not what I want
            e.Row.Cells[4].Text = process(e.Row.Cells[4].Text);
        }
    }

    public SqlDatasource getGridViewDataSource() {//Customer sql data source}
    public string process(string) {//Customer code}

The code follows the sample provided here. The question is, what else is changed except altering the displayed text? What if I really want it to still be editable? MSDN does not seem to explain that bit. Anyone can help?


Solution

  • In the example from the article there is no custom OnRowEditing event. Your function gv.DataBind() triggers OnRowDataBound twice - first time with filled values, second time without it (Row in edit state). So your function should look like this:

        public void OnRowDataBound(Object sender, GridViewRowEventArgs e)
        {
            // convert time display to another format
            if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowState != DataControlRowState.Edit)
            {
                e.Row.Cells[4].Text = process(e.Row.Cells[4].Text);
            }
        }
    

    Adding if check is also a good idea, but in this case can be not necessary:

        public void OnRowDataBound(Object sender, GridViewRowEventArgs e)
        {
            // convert time display to another format
            if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowState != DataControlRowState.Edit)
            {
                if(!string.IsNullOrEmpty(e.Row.Cells[4].Text))
                    e.Row.Cells[4].Text = process(e.Row.Cells[4].Text);
            }
        }