I am using ASP.NET Dynamic Data to generate a web site for several data tables, and so far so good.
But there is a request from the customer that they want to merge cells with equal values in the GridView.
I have got a solution CodeProject and it works well in a normal ASP.NET page.
However, it simply merges all the rows into one row in a Dynamic Data generated GridView.
I traced the source code and find out that in the GridView_PreRender
method, the row.Cells[cellIndex].Text
is always empty!
SO, I can not judge if two cells are the same. Is anyone have encountered such problem before?
Based on my research in order to get values of GridView's
cells on PreRender
event in ASP.NET Dynamic Data you need to do the following things:
FieldTemplate
in the cell's controls collectionFieldTemplate
to FieldTemplateUserControl
to gain access to it propertiesI have just simulated your problem based on my project.
List.aspx.cs:
protected void gvOffices_PreRender(object sender, EventArgs e)
{
for (int rowIndex = gvOffices.Rows.Count - 2; rowIndex >= 0; rowIndex--)
{
GridViewRow row = gvOffices.Rows[rowIndex];
GridViewRow previousRow = gvOffices.Rows[rowIndex + 1];
if (row.RowType == DataControlRowType.DataRow)
{
for (int i = 0; i < row.Cells.Count; i++)
{
string dataField = ((DynamicField)((DataControlFieldCell)row.Cells[i]).ContainingField).DataField;
Control dataControl = ((FieldTemplateUserControl)((DynamicControl)row.Cells[i].FindDynamicControlRecursive(dataField)).FieldTemplate).DataControl;
string cellText = ((Literal)dataControl).Text; // for text fields
string dataFieldPrev = ((DynamicField)((DataControlFieldCell)previousRow.Cells[i]).ContainingField).DataField;
Control dataControlPrev = ((FieldTemplateUserControl)((DynamicControl)previousRow.Cells[i].FindDynamicControlRecursive(dataField)).FieldTemplate).DataControl;
string cellTextPrev = ((Literal)dataControl).Text; // for text fields
Response.Write(cellText);
Response.Write(cellTextPrev);
//if (cellText == cellTextPrev)
//{
// row.Cells[i].RowSpan = previousRow.Cells[i].RowSpan < 2 ? 2 :
// previousRow.Cells[i].RowSpan + 1;
// previousRow.Cells[i].Visible = false;
//}
}
}
}
}
FindDynamicControlRecursive()
you can find at http://csharpbits.notaclue.net/2009/01/dynamic-data-cascading-fieldtemplates.html.
Consider this technique in your project. I hope this will help.
EDIT 1:
Also we need to check if a control inside GridView cell is HyperLink
or Literal
:
if (dataControl is Literal)
{
cellText = ((Literal)dataControl).Text;
}
else
{
if (dataControl is HyperLink)
{
cellText = ((HyperLink)dataControl).Text;
}
}
EDIT 2: (It works fine for me)
Check if a control inside GridView cell is DynamicField
:
protected void gvOffices_PreRender(object sender, EventArgs e)
{
for (int rowIndex = gvOffices.Rows.Count - 2; rowIndex >= 0; rowIndex--)
{
GridViewRow row = gvOffices.Rows[rowIndex];
GridViewRow previousRow = gvOffices.Rows[rowIndex + 1];
if ((row.RowType == DataControlRowType.DataRow) && (previousRow.RowType == DataControlRowType.DataRow))
{
for (int i = 0; i < row.Cells.Count; i++)
{
// check for the current row
if (((DataControlFieldCell)row.Cells[i]).ContainingField is DynamicField)
{
string dataField = ((DynamicField)((DataControlFieldCell)row.Cells[i]).ContainingField).DataField;
Control dataControl = ((FieldTemplateUserControl)((DynamicControl)row.Cells[i].FindDynamicControlRecursive(dataField)).FieldTemplate).DataControl;
string cellText = string.Empty;
if (dataControl is Literal)
{
cellText = ((Literal)dataControl).Text;
}
else
{
if (dataControl is HyperLink)
{
cellText = ((HyperLink)dataControl).Text;
}
}
// get cells text of the current row
Response.Write(cellText);
}
// check for the previous row
if (((DataControlFieldCell)previousRow.Cells[i]).ContainingField is DynamicField)
{
string dataFieldPrev = ((DynamicField)((DataControlFieldCell)previousRow.Cells[i]).ContainingField).DataField;
Control dataControlPrev = ((FieldTemplateUserControl)((DynamicControl)previousRow.Cells[i].FindDynamicControlRecursive(dataFieldPrev)).FieldTemplate).DataControl;
string cellTextPrev = string.Empty;
if (dataControlPrev is Literal)
{
cellTextPrev = ((Literal)dataControlPrev).Text;
}
else
{
if (dataControlPrev is HyperLink)
{
cellTextPrev = ((HyperLink)dataControlPrev).Text;
}
}
// get cells text of the previous row
Response.Write(cellTextPrev);
}
// Try to merge cells
//if (cellText == cellTextPrev)
//{
// row.Cells[i].RowSpan = previousRow.Cells[i].RowSpan < 2 ? 2 :
// previousRow.Cells[i].RowSpan + 1;
// previousRow.Cells[i].Visible = false;
//}
}
}
}
}