Programatically choosing a variable number of gridview rows to format - c#

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?

Related

How to get first and last row in Gridview?

I have a gridview which binds data on page load:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindCustomerData();
}
}
I would like to display different buttons depending on the criteria. For simplicity
If its the first gridview row then display "First Record"
If its the last gridview row then display "Last Record"
Any other row "Middle Record"
All buttons start with Visible = False on the markup.
In my RowDataBound event i have
protected void gvCusts_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
int lastIndex = gvCusts.Rows.Count -1;
if (e.Row.RowType == DataControlRowType.DataRow)
{
Button buttonFirst = (Button)e.Row.FindControl("buttonFirst");
Button buttonMiddle = (Button)e.Row.FindControl("buttonMiddle");
Button buttonLast = (Button)e.Row.FindControl("buttonLast");
// Customer Records found
if (c.Id > 0)
{
if (e.Row.RowIndex == 0)
{
// First row so display first button only
buttonFirst.Visible = true;
}
else if (e.Row.RowIndex >= 1 && e.Row.RowIndex <= lastIndex)
{
// Not the first row and not the last row so display the middle button only
buttonMiddle.Visible = true;
}
else if (e.Row.RowIndex == lastIndex)
{
// Last row, so display the last button only.
buttonLast.Visible = true;
}
}
}
}
The problem is i cant find a proper way to get the middle and last rows and have buttons showing at the wrong stages.
I then made the int lastIndex = gvCusts.Rows.Count -1; line of code static and still not getting the correct results.
I've read a number of articles so obviously i'm missing something somewhere but not sure what?
Declare a static variable rowCount in your class.
int rowCount=0;
In your BindCustomerData() method, pass the number of rows to rowCount variable.
rowCount= YourDataTable.Rows.Count-1;
Now, get first and last index from rowCount Variable.
protected void gvCusts_RowDataBound(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
int lastIndex = rowCount;//rowCount has the last index
if (e.Row.RowType == DataControlRowType.DataRow)
{
Button buttonFirst = (Button)e.Row.FindControl("buttonFirst");
Button buttonMiddle = (Button)e.Row.FindControl("buttonMiddle");
Button buttonLast = (Button)e.Row.FindControl("buttonLast");
// Customer Records found
if (c.Id > 0)
{
if (e.Row.RowIndex == 0)
{
// First row so display first button only
buttonFirst.Visible = true;
}
else if (e.Row.RowIndex >= 1 && e.Row.RowIndex < rowCount)
{
// Not the first row and not the last row so display the middle button only
buttonMiddle.Visible = true;
}
else if (e.Row.RowIndex == rowCount)
{
// Last row, so display the last button only.
buttonLast.Visible = true;
}
}
}
}

Custom cell merged

I need to display data in gridview with merged rows for some columns.
the original data from database like:
please help me to display gridview like:
for column transaksi merged by tgl
for column priority , price , creted by merged by transaksi
Using C#, how can I prepare a gridview for the format? Please help me.
I suggest you to go through documentation - Tutorial: Cell Merging
To implement custom cell merge use the GridView.CellMerge event
handler. First, check if the correct column is being processed. Then,
obtain display texts for the two cells being compared. Finally,
indicate that cells are to be merged if their display texts match. Set
the CellMergeEventArgs.Handled parameter to true to override the
grid's default processing for this column.
Example:
using DevExpress.XtraGrid.Views.Grid;
// ...
private void gridView1_CellMerge(object sender, DevExpress.XtraGrid.Views.Grid.CellMergeEventArgs e) {
GridView view = sender as GridView;
if(view == null) return;
if (e.Column == colCreatorID) {
string text1 = view.GetRowCellDisplayText(e.RowHandle1, colCreatorID);
string text2 = view.GetRowCellDisplayText(e.RowHandle2, colCreatorID);
e.Merge = (text1 == text2);
e.Handled = true;
}
}
Use your own conditions while processing a column. for example take transaksi 005, In this case check values of row 5 and 6 then compare column created by for equality depends upon your condition set the e.Merge to true.
I just picked response posted on this topic and added one line to achieve what you want.
bool IsTheSameCellValue(int column, int row)
{
// To compare only values on 1st and 2nd column (TGL, TRANSAKSI)
if (column > 1) return false;
DataGridViewCell cell1 = dataGridView[column, row];
DataGridViewCell cell2 = dataGridView[column, row - 1];
if (cell1.Value == null || cell2.Value == null)
{
return false;
}
return cell1.Value.ToString() == cell2.Value.ToString();
}
private void dataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
e.AdvancedBorderStyle.Bottom = DataGridViewAdvancedCellBorderStyle.None;
if (e.RowIndex < 1 || e.ColumnIndex < 0)
return;
if (IsTheSameCellValue(e.ColumnIndex, e.RowIndex))
{
e.AdvancedBorderStyle.Top = DataGridViewAdvancedCellBorderStyle.None;
}
else
{
e.AdvancedBorderStyle.Top = dataGridView.AdvancedCellBorderStyle.Top;
}
}
private void dataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.RowIndex == 0)
return;
if (IsTheSameCellValue(e.ColumnIndex, e.RowIndex))
{
e.Value = "";
e.FormattingApplied = true;
}
}
However it's impossible to center text vertically in merged cells with this solution because it only erases the borders and not totally redraw the component.

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

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;
}
}
}

Highlight gridview row based on datatable values

I need to highlight gridview rows based on values from datatable.
I have highlighted values like if any particular cell values has met some conditions then I can highlight using this code.
if(int.Parse(DataBinder.Eval(e.Row.DataItem,"Risk").ToString()) > 100)
{
e.Row.BackColor = Color.FromName("#FAF7DA");
}
Now my questions is, in my rowdatabound event I want to check values in datatable and I need to highlight values in the gridview.
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataTable dt = DataRepository.highlightRow();
string[] strInactive = dt.AsEnumerable().Select(row => row.Field<string>("product_id")).ToArray();
foreach (GridViewRow row in gvProducts.Rows)
{
for (int i = 0; i < gvProducts.Columns.Count; i++)
{
if (gvProducts.Rows[0].Cells[0].Text.Contains("how to pass array values"))
{
e.Row.BackColor = System.Drawing.Color.Red;
}
}
}
}
}
For ex:
Here the datatable will return only one column values like this,10, 20, 20. Then I need to highlight rows of these values in the gridview.
you should be able to check e.Row.DataItem for values that meet your criteria
You can do something like this in the RowDataBound event:
if (e.Row.RowType == DataControlRowType.DataRow) {
DataRowView drv = (DataRowView) e.Row.DataItem;
if( drv("Risk") == <some condition> ) {
e.Row.BackColor = Drawing.Color.Black // :)
}
}
Perhaps this is what you are looking for:
private const System.Drawing.Color HIGHLIGHT = System.Drawing.Color.Yellow;
private const System.Drawing.Color NORMAL = System.Drawing.Color.White;
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataTable dt = DataRepository.highlightRow();
string[] strInactive = dt.AsEnumerable().Select(row => row.Field<string>("product_id")).ToArray();
foreach (var value in strInactive)
{
e.Row.BackColor = (e.Row.Cells[0].Text == value) ? HIGHLIGHT : NORMAL;
}
}
}
I do not know what is in your DataTable, so I don't know what you want to test for.

Gridview Dynamic formatting according to conditions

I have this code on RowDataBound that alternates the color of the cells and also add an onclick event on the cells. The data comes dynamically from a stored procedure so the gridview has only one control. The ButtonField.
I want to have white color for cells that hasn’t any data inside, how can I achieve this?
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
{
string back1 = "url('Images/GridBack1.jpg')";
string back2 = "url('Images/GridBack2.jpg')";
if (e.Row.RowType != DataControlRowType.DataRow)
return;
for (int i = 0; i < e.Row.Cells.Count; i++)
{
TableCell Cell = e.Row.Cells[i];
// if both row and column are odd, color them black
// if both row and column are even, color them white
if (((e.Row.RowIndex % 2 == 1) && (i % 2 == 1)) ||
((e.Row.RowIndex % 2 == 0) && (i % 2 == 0)))
{
if (string.IsNullOrEmpty(e.Row.Cells[i].Text)) //Edit
{
e.Row.Cells[i].BackColor = Color.Blue;
e.Row.Cells[i].ForeColor = Color.White;
}
else
{
e.Row.Cells[i].Width = Unit.Pixel(450);
e.Row.Cells[i].Height = Unit.Pixel(67);
e.Row.Cells[i].Style.Add("background-image", back1);
//e.Row.Cells[i].Style.Add("width", "150px");
//e.Row.Cells[i].Style.Add("word-wrap","break-word");
e.Row.Cells[i].Attributes.Add("align", "center");
}
}
else
{
if (string.IsNullOrEmpty(e.Row.Cells[i].Text)) //Edit
{
e.Row.Cells[i].BackColor = Color.Blue;
e.Row.Cells[i].ForeColor = Color.White;
}
else
{
e.Row.Cells[i].Width = Unit.Pixel(450);
e.Row.Cells[i].Height = Unit.Pixel(67);
e.Row.Cells[i].Style.Add("background-image", back2);
//e.Row.Cells[i].Style.Add("width", "150px");
//e.Row.Cells[i].Style.Add("word-wrap", "break-word");
e.Row.Cells[i].Attributes.Add("align", "center");
}
}
string color = "#000000";
e.Row.Cells[0].Attributes.Add("Style", "background-color: " + color + ";");
e.Row.Cells[0].Width = Unit.Pixel(150);
e.Row.Cells[0].Height = Unit.Pixel(67);
}
if (e.Row.RowType == DataControlRowType.DataRow)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
LinkButton _singleClickButton = (LinkButton)e.Row.Cells[0].Controls[0];
string _jsSingle = ClientScript.GetPostBackClientHyperlink(_singleClickButton, "");
// Add events to each editable cell
for (int columnIndex = 2; columnIndex < e.Row.Cells.Count; columnIndex++)
{
// Add the column index as the event argument parameter
string js = _jsSingle.Insert(_jsSingle.Length - 2, columnIndex.ToString());
// Add this javascript to the onclick Attribute of the cell
e.Row.Cells[columnIndex].Attributes["onclick"] = js;
// Add a cursor style to the cells
e.Row.Cells[columnIndex].Attributes["style"] += "cursor:pointer;cursor:hand;";
}
}
}
}
Try to assign white color to the every cell and then overwrite according to conditions.
You need to use string.IsNullOrEmpty() like
if(string.IsNullOrEmpty(e.Row.Cells[i].Text))
{
e.Row.Cells[i].BackColor = Color.Blue;
e.Row.Cells[i].ForeColor = Color.White;
}
MSDN
Hope it works.

Categories

Resources