Question

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?

Was it helpful?

Solution

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:

  1. Find the FieldTemplate in the cell's controls collection
  2. Cast FieldTemplate to FieldTemplateUserControl to gain access to it properties

I 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;
                //}
            }
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top