BulkEditGridView adjustments

Topics: Developer Forum, User Forum
Jun 29, 2007 at 4:54 AM
Thanks Matt for this terrific control, we have 2 people in this office using it right now for production sites! Thanks also to the other posters like Borge, tomwood who have provided useful adjustments.

Addressing some of the issues with DropDowns and Insert Rows in the BulkEditGridView, here are the adjustments I made to get it working for us.

To get DropDowns populating themselves in insert rows:
In the class DropDownField.cs HandleDataBinding, replace the lines

object rawVal = GetValue(ctrl.NamingContainer);
string val = (null == rawVal ? null : rawVal.ToString());

with the following (probably a better way to do this I guess but it works for now)

object rawVal = null;
try
{
rawVal = GetValue(ctrl.NamingContainer);
}
catch (HttpException ex)
{
// it's an insert row, populate the drop down anyway
}
string val = (null == rawVal ? null : rawVal.ToString());

And then add the following to BulkEditGridView.CreateInsertRow()

// populate any dropdowns
foreach (Control ctrl in row.Controls)
{
if (ctrl.Controls0 is DropDownList)
{
((DropDownList)ctrl.Controls0).DataBind();
}
}


To create just one header row for an empty grid when you have insert rows
Remove the create header row code from the CreateInsertRow method & put it into both OnPagePreLoad and OnDataBound instead. The methods now look like so (including Borge's changes plus the first one above):
(Sorry about the formatting here, the square brackets are being transformed to urls incorrectly)

/// <summary>
/// We have to recreate our insert row so we can load the postback info from it.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected override void OnPagePreLoad(object sender, EventArgs e)
{
base.OnPagePreLoad(sender, e);

if (this.EnableInsert && this.Page.IsPostBack)
{
CreateHeaderRow();
for (int i = 0; i < this.InsertRowCount; i++)
this.CreateInsertRow();
}
}

/// <summary>
/// After the controls are databound, add a row to the end.
/// </summary>
/// <param name="e"></param>
protected override void OnDataBound(EventArgs e)
{
if (this.EnableInsert)
{
CreateHeaderRow();
for (int i = 0; i < this.InsertRowCount; i++)
this.CreateInsertRow();
}

base.OnDataBound(e);
}

/// <summary>
/// Creates header row for empty data.
/// </summary>
private void CreateHeaderRow()
{
if (this.Rows.Count == 0)
{
this.Controls.Add(new Table());
GridViewRow header = this.CreateRow(0, -1, DataControlRowType.Header, DataControlRowState.Normal);
DataControlField[] fields = new DataControlFieldthis.Columns.Count;
this.Columns.CopyTo(fields, 0);
this.InitializeRow(header, fields);
//this.CreateChildTable();
this.InnerTable.Rows.Add(header);

}
}

/// <summary>
/// Creates the insert row and adds it to the inner table.
/// </summary>
protected virtual void CreateInsertRow()
{
GridViewRow row = this.CreateRow(this.Rows.Count, -1, DataControlRowType.DataRow, DataControlRowState.Insert);

DataControlField[] fields = new DataControlFieldthis.Columns.Count;
this.Columns.CopyTo(fields, 0);

row.ApplyStyle(this.insertRowStyle);

this.InitializeRow(row, fields);

if (this.InnerTable != null)
{
int index = this.InnerTable.Rows.Count - (this.ShowFooter ? 1 : 0);
this.InnerTable.Rows.AddAt(index, row);
}

// populate any dropdowns
foreach (Control ctrl in row.Controls)
{
if (ctrl.Controls0 is DropDownList)
{
((DropDownList)ctrl.Controls0).DataBind();
}
}

//Disable RequiredFieldValidator if present.
//Remove delete button if present.
for (int i = 0; i < row.Cells.Count; i++)
{
for (int j = 0; j < row.Cellsi.Controls.Count; j++)
{
if (row.Cellsi.Controlsj is RequiredFieldValidator)
{
((RequiredFieldValidator)row.Cellsi.Controlsj).Enabled = false;
}
else if (row.Cellsi.Controlsj is LinkButton)
{
LinkButton linkButton = (LinkButton)row.Cellsi.Controlsj;
if (linkButton.CommandName.ToLower() == "delete")
{
linkButton.Enabled = false;
linkButton.Visible = false;
}
}
}
}
}

I hope this helps someone.
Thanks again