GridView: OnRowDatabound HeaderText Equals to ColumnText with AutoGenerateColumn True c# Asp.net - c#

I have a gridview with first columns is same as headers i.e. same value with autogeneratecolumns as true, what i need to do in RowDatabound if HeaderText Equals to Intersect of the first Column text, Change the color to Yellow. Please see the attached image of the Desireed Gridview Output.
GridViewDesiredOutput
HTML
<asp:GridView ID="GvSamples" OnRowDataBound="GvSamples_RowDataBound" runat="server" AutoGenerateColumns="True">
C#
public void BindSamplesGrid()
{
DataTable _dt = new DataTable();
_dt = BL.GetSample(_conn);
GvSamples.DataSource = _dt;
GvSamples.DataBind();
}
protected void GvSamples_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
for (int i = 0; i < e.Row.Cells.Count; i++)
{
if (e.Row.Cells[i].Text == e.Row.Cells[i].Text)
e.Row.Cells[i].Text = e.Row.Cells[i].Text.Replace("_", " ");
}
}
}
I am using asp.net C# Gridview.
Thank you

There are a couple of issues with your code. First of all you can only access the header row in DataControlRowType.Header, so coloring the cells as desired must be done in DataControlRowType.DataRow.
Next you are evaluating exactly the same value, so it will always be true: e.Row.Cells[i].Text == e.Row.Cells[i].Text, although this does not seem to do much except replace a _, which has nothing to do with getting the cell color to be yellow.
The below snippet does what you need. It gets the current row number and colors the correct cell yellow.
protected void GvSamples_RowDataBound(object sender, GridViewRowEventArgs e)
{
//check if the row is a datarow
if (e.Row.RowType == DataControlRowType.DataRow)
{
//get the current row number
int rowIndex = e.Row.RowIndex;
//check if the rownumber does not exceed the column count
if (rowIndex < e.Row.Cells.Count - 1)
{
//make the cell yellow
e.Row.Cells[rowIndex + 1].BackColor = Color.Yellow;
}
}
}

Related

How to keep 'Absent' text in the place of 'Empty' cell base on Current HeaderName Date in gridview row data bound

Trying cell value should be 'Absent' if cell is empty base on headertext date less than and equal to today date that cell should empty, below 12,13 dates are matching with below condition but how to cell field absent base on header text date, header condition is matching with below if condition but not getting how to keep absent.
protected void gridview_trainees_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
GridView gridView = (GridView)sender;
var colCount = gridview_trainees.Columns.Count;
for (int i = 3; i < colCount; i++)
{
BoundField columField = (BoundField)((DataControlFieldCell)e.Row.Cells[i]).ContainingField;
DateTime CurrentColumndate = DateTime.Parse(columField.HeaderText);
if (CurrentColumndate.Date <=DateTime.Now.Date)
{
//trying cell value should be absent if cell is empty base on header
}
}
}
}
My current gridview is like below
I want ouput like this, if header text date <= today date that column empty cell should be 'Absent'
I don't typically use the default GridView and this may not be the best approach but I suspect that since there's no way to directly retrieve the CellIndex based on the Cell's HeaderRow value, it's easier to make a list of the CellIndex values that match the date criteria.
Then iterate through that list to conditionally change text in cells where the Cell.Text value matches the empty criteria.
Add a page property:
private List<int> ColIndexes = new List<int>();
This is my proposed solution based on a similar situation:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
var row = e.Row;
if(row.RowType == DataControlRowType.Header)
{
foreach(TableCell cell in row.Cells)
{
if(DateTime.TryParse(cell.Text, out var date))
{
if(date <= DateTime.Now.Date)
ColIndexes.Add(row.Cells.GetCellIndex(cell));
}
}
}
if(row.RowType == DataControlRowType.DataRow)
{
foreach (var index in ColIndexes)
{
var cell = row.Cells[index];
if (string.IsNullOrWhiteSpace(cell.Text))
cell.Text = "Absent";
}
}
}

Changing Row Color of DataGridView Based on Cell Value

I have Data Gridview with 2 columns namely Filename and Status .The DataGridview has a Datasource setup like this
var bs = new BindingSourceAsync();
bs.DataSource = data;
dataGridView4.DataSource = bs;
The value of the Status Column is Updated using async-await method.When the Status Value is "Invalid" i need to change the the corresponding row color to red and green if its "Valid".
For this purpose i tried hooking to the CellValueChanged Event of the DataGridView
dataGridView4.CellValueChanged += DataGridView4_CellValueChanged;
But the Event is never fired.How can i solve this problem.Please advice.
yes, In RowDataBound for the gridview
protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs e)
{
// check if it is the DataRow not the header row
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Cell[1] is the cell contain the value for the condition
if (Convert.ToInt16(e.Row.Cells[1].Text) < 10)
{
e.Row.Cells[0].BackColor = System.Drawing.Color.Yellow;
e.Row.Cells[1].BackColor = System.Drawing.Color.Yellow;
}
else if (Convert.ToInt16(e.Row.Cells[1].Text) < 30)
{
e.Row.Cells[0].BackColor = System.Drawing.Color.Blue;
e.Row.Cells[1].BackColor = System.Drawing.Color.Blue;
}
}
}

How to achieve multiple colspan and multiple header row using ASP.Net gridview?

I'm in a situation were need to achieve multiple colspan and two header row using ASP.Net gridview.
Something like below
+----------+--------------------------------+--------------------------------+
|Name |English |Math |
| |----------+----------+----------+----------+----------+----------+
| |1st Term |2nd Term |3rd Term |1st Term |2nd Term |3rd Term |
+----------+----------+----------+----------+----------+----------+----------+
|Adam |50 |60 |70 |55 |65 |75 |
+----------+----------+----------+----------+----------+----------+----------+
|Smith |52 |62 |72 |57 |68 |70 |
+----------+----------+----------+----------+----------+----------+----------+
Is it possible to do it?
Edit : Number of rows and / or columns or even sub-headers of a header is not fixed.
Access to the RowSpan and ColumnSpan for a grid view is done through the Cells property.
To access the header cells:
//Replace ColumnSpan with RowSpan if needed (and if you can get multiple header rows)
Gridview1.HeaderRow.Cells[CELL_INDEX].ColumnSpan = 2; //Need to know the cell index
To access the cells of a normal row:
//Replace ColumnSpan with RowSpan if needed
Gridview1.Rows[ROW_INDEX].Cells[CELL_INDEX].ColumnSpan = 2; //Need to know the row index and the cell index in that row
The multiple header row might be a bit more tricky. I've never done it, but the guy here seemed to have a good answer: How to add Header and Subheader in Gridview
It can be done, but it takes a bit of trial and error to get the design you want. Use the GridView OnRowDataBound event. It would be easier to do this after the GridView is build, especially for RowSpan.
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
int spanColumn_1_start = 1;
int spanColumn_1_length = 3;
//apply colspan
e.Row.Cells[spanColumn_1_start].ColumnSpan = 3;
//remove the spanned cells
for (int i = 1; i < spanColumn_1_length; i++)
{
e.Row.Cells.RemoveAt(spanColumn_1_start + 1);
}
//note that the startindex of the 2nd colspan is set after removing cells for 1st colspan
int spanColumn_2_start = 2;
int spanColumn_2_length = 3;
//apply colspan
e.Row.Cells[spanColumn_2_start].ColumnSpan = 3;
//remove the spanned cells
for (int i = 1; i < spanColumn_2_length; i++)
{
e.Row.Cells.RemoveAt(spanColumn_2_start + 1);
}
}
else if (e.Row.RowType == DataControlRowType.DataRow)
{
int rowIndex = e.Row.DataItemIndex;
//to make a rowspan you have to work backwards since the next row does not exist yet
if (rowIndex == 1)
{
GridView1.Rows[rowIndex - 1].Cells[0].RowSpan = 2;
e.Row.Cells.RemoveAt(0);
}
//span 4 rows in column 3 starting at row 6
if (rowIndex == 9)
{
int rowSpan = 4;
int columnIndex = 3;
//apply rowspan
GridView1.Rows[rowIndex - rowSpan].Cells[columnIndex].RowSpan = rowSpan;
//remove the spanned rows
for (int i = 1; i < rowSpan; i++)
{
GridView1.Rows[rowIndex - (rowSpan - i)].Cells.RemoveAt(columnIndex);
}
}
}
}
The above snippet will give the following result.
UPDATE
To add an extra header row you need to use the OnRowCreated event of the GridView.
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
//cast the sender back to a gridview
GridView gv = sender as GridView;
//check if the row is the header row
if (e.Row.RowType == DataControlRowType.Header)
{
//create a new row
GridViewRow extraHeader = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert);
extraHeader.BackColor = Color.Green;
//loop all the columns and create a new cell for each
for (int i = 0; i < gv.Columns.Count; i++)
{
TableCell cell = new TableCell();
cell.Text = "ExtraHeader " + i;
//add the cell to the new header row
extraHeader.Cells.Add(cell);
}
//add the new row to the gridview
gv.Controls[0].Controls.AddAt(0, extraHeader);
}
}

How to set columns width in a Dynamic Gridview?

How to set columns width in a Dynamic Gridview? When AutoGenerateColumns="true"
You can have a serverside method as below:
private void GV_RowDataBound(object o, GridViewRowEventArgs e)
{
// apply custom formatting to data cells
if (e.Row.RowType == DataControlRowType.DataRow)
{
// set formatting for the category cell
TableCell cell = e.Row.Cells[0];
cell.Width = new Unit("120px");
cell.Style["border-right"] = "2px solid #666666";
// set formatting for value cells
for(int i=1; i<e.Row.Cells.Count; i++)
{
cell = e.Row.Cells[i];
// right-align each of the column cells after the first
// and set the width
cell.HorizontalAlign = HorizontalAlign.Right;
cell.Width = new Unit("90px");
// alternate background colors
if (i % 2 == 1)
cell.BackColor
= System.Drawing.ColorTranslator.FromHtml("#EFEFEF");
// check value columns for a high enough value
// (value >= 8000) and apply special highlighting
}
}
// apply custom formatting to the header cells
if (e.Row.RowType == DataControlRowType.Header)
{
foreach (TableCell cell in e.Row.Cells)
{
cell.Style["border-bottom"] = "2px solid #666666";
cell.BackColor=System.Drawing.Color.LightGray;
}
}
}
}
Your aspx page
<asp:GridView id="myList" runat="server"
AutoGenerateColumns="true"
OnRowDataBound="GV_RowDataBound"
. . .
>
</asp:GridView>
For detailed information you can check here
You need to make changes to RowDataBound event of gridview like this
protected void gvData_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow) {
e.Row.Cells(0).Width = new Unit("200px");
e.Row.Cells(1).Width = new Unit("500px");
}
}
Your markup
<asp:GridView id="gvData" runat="server"
OnRowDataBound="gvData_RowDataBound">
</asp:GridView>
By default autogeneratecolumn is false so no need to specify autogeneratecolumn="true"

Programatically choosing a variable number of gridview rows to format

I have a gridview where I format a specific number of cells for specific rows:
protected void hoursReportGridView_OnRowDataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (e.Row.RowIndex == 1 || e.Row.RowIndex == 2)
{
for (int i = 0; i < 14; i++)
{
e.Row.Cells[i].ForeColor = Color.Black;
e.Row.Cells[i].BackColor = ColorTranslator.FromHtml("#EAFDB3");
e.Row.Cells[i].Font.Bold = true;
}
}
}
}
Right now, the rows that get changed are static (row 1 and 2).
I've added functionality to the gridview and now need a dynamic number of rows formatted (between 2 and 10). The rows will always be next to eachother.
How can choose the rows dynamically?

Categories

Resources