Risho
Risho

Reputation: 2647

Formatting data in the GridView at OnRowDataBound event

I have a GridView in which the first column display redundant data in a set of three. I need to eliminate this redundancy so to that only one instance of the code is displayed.

Here is what the GridView looks like:

A1234 | Total Entries                  | 1    | 7   |     |                   
A1234 | Equipment Entries              | 1    | 7   |     |                 
A1234 | Total Repair Time              | 60   | 140 |     |                   
B9876 | Total Entries                  | 87   | 36  | 14  | 
B9876 | Equipment Entries              | 87   | 36  | 143 | 
B9876 | Total Repair Time              | 2070 | 790 | 370 |   
C3456 | Total Entries                  | 1    |     |     |        
C3456 | Equipment Entries              | 1    |     |     |       
C3456 | Total Repair Time              | 190  |     |     | 

What I want it to look like is (and I can't seem get it formatted properly) so that in the first column the codes A1234, B9876, and C3456 only display once rather than three time as it is shown - so that there is black space/cell.

The latest code that I have is basically this:

protected void gvMetrics_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {   
        DataRow _data = ((DataRowView)e.Row.DataItem).Row;

        // _lastCode is a clas level variable
        if (_lastCode.ToString() != _data.ItemArray[0].ToString())
        {
            if (_totals == 1)
            {
                _lastCode = _data.ItemArray[0].ToString();
                e.Row.Cells[0].Text = _data.ItemArray[0].ToString();
               _totals++;
            }  
         }
         else
          _totals = 1; // Class level variable initialized to 1.
     }
 }

For some reason I am not able to format the code but you get the picture. What my reasoning here is that I would assign the code to the class variable and with each OnRowDataBaound event I would check if the value matches with the current cell. If it matches skip writing to the GridView/page. That did not work so I thought I can use a counter which reset itself to 1 after third event - again that didn't work.

I feel like I'm so close but no cigar! I would imagine this nothing new under the sun so if some can kindly suggest a solution, I would greatly appreciate it!

Upvotes: 1

Views: 586

Answers (1)

Kelsey
Kelsey

Reputation: 47736

The best way to do this is make the first column into a TemplateField and add a Literal with the OnDataBinding event implemented.

Example:

<asp:TemplateField>
    <ItemTemplate>
        <asp:Literal ID="ltYourField" runat="server"
            OnDataBinding="ltYourField_DataBinding" />
    </ItemTemplate>
</asp:TemplateField>

Then in your .cs codebehind:

// Create a global to store last value found for the field
string _lastValueDisplayed = string.Empty;

Implement the OnDataBinding:

protected void ltYourField_DataBinding(object sender, System.EventArgs e)
{
    Literal lt = (Literal)sender;
    string displayValue = Eval("yourFieldNameFromResult").ToString();
    lt.Text = _lastValueDisplayed.Equals(displayValue) ?
        string.Empty : displayValue;
    // store value for checking on next row
    _lastValueDisplayed = displayValue;
}

Try not to do binding stuff in the OnRowDataBound because then your code has to look for controls. If you tie the functionality to the control in question using the OnDataBinding instead, it scopes your code specifically to the control you want and there is no searching.

Upvotes: 2

Related Questions