Reputation: 2647
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
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