Change Style of rows created by ListView in itemCreated event - c#

When render a databound ListView I want to dynamically set the background colour of each row depending on the results, in my case Red, Orange and Green.
protected void ListView1_ItemCreated(object sender, ListViewItemEventArgs e)
{
DataRow myRow;
DataRowView myRowView;
myRowView = (DataRowView)e.Item.DataItem;
myRow = myRowView.Row;
if (myRow[2].ToString().CompareTo("") == 1)
{
// Colour coding here..
}
}
Is it possible to reach the TR tag for each row to change the style?
Many thanks,
Stefan

The TR tag would have to have runat="server" to use server-side code; however, you may be able to inject it in without that by examining the controls that are the child of the item; there's probably a Literal or LiteralControl with the HTML, and you can use string manipulation to inject...

I worked out a solution to my problem, with some good help from Brian.
I have a ListView and I added an id tag (trRow) and tag runat="server" like this:
<AlternatingItemTemplate>
<tr id="trRow" runat="server" style="background-color:#FFF8DC;">
In code behind it looks like this:
protected void ListView1_ItemCreated(object sender, ListViewItemEventArgs e)
{
DataRow myRow;
DataRowView myRowView;
myRowView = (DataRowView)e.Item.DataItem;
myRow = myRowView.Row;
System.Web.UI.HtmlControls.HtmlTableRow myTR = (System.Web.UI.HtmlControls.HtmlTableRow)e.Item.FindControl("trRow");
if (myRow[2].ToString().CompareTo("") == 1)
{
myTR.Style.Value = "background-color:#FF0000;color: #000000;";
} else
myTR.Style.Value = "background-color:#00FF00;color: #000000;";
}
Some of the logic in there is still not correct etc, just to show how I solved the issue to dynamically change the background color of each row.

Related

How to find all textboxes in a gridview row?

I have a GridView on a website, that have different controls in each row (eg.: textbox, label, dropdownlist). I need to find all textboxes and set the enabled property to false, so the user won't be able to edit them. I tried the code below, but it dosn't work, 'c' never recognised as a textbox, so it never changes the property.
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (a)
{
foreach (Control c in e.Row.Controls)
{
if (c is TextBox)
{
((TextBox)(c)).Enabled = false;
}
}
}
}
I think you should try like this:
TextBox tb = e.Row.FindControl("textbox_name") as TextBox;
tb.Enabled = false;
Your textboxes must be nested within other controls, most likely cells inside the row. That is why you cannot find them just iterating through immediate children.
If you have a list of IDs of the text boxes, you should use FindControl:
((TextBox)e.Row.FindControl("TextBoxID")).Enabled = false;
Otherwise you will need to recursively find your controls of necessary type. See this thread for code sample.
One more option, if a is relatively easy to calculate, is to use in the markup directly, like so:
<asp:TextBox ... Enabled='<%# a %>' />
This depends a lot on the details of how a is derived. If it is a protected or public field of the page class, just the code above should work. If it is calculated based on row, you may need to turn it into protected method and pass params into it:
Enabled='<%# GetEnabled(Eval("Prop1"), Eval("Prop2")) %>'
And also want to put some updation.
There are different types of rows in gridview (header,footer,datarow,etc)
so for making little faster for the control find.
Try below (check the if condition)
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Find the TextBox control.
TextBox txtName = (e.Row.FindControl("txtName") as TextBox);
txtName.Enabled = false;
//or
TextBox txtName1 = (TextBox)e.Row.FindControl("txtName");
txtName1.Enabled = false;
}
}
You should search controls inside the cell instead of Row.
foreach (TableCell cell in e.Row.Cells)
{
foreach (Control c in cell.Controls)
{
if (c is TextBox)
{
((TextBox)(c)).Enabled = false;
}
}
}

How to set the background color on a gridview row

I was trying fire a row data bind event to a grid view. When data is being bound to grid view, i would like to check a condidtion , if the condidtion is satisfied , then i need to apply some color to that entire row..Please check the below code i am using..
protected void GridView4_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Textbox txtBox1 = (GridView)(e.Row.FindControl("Name of text box"));
if(Condidtion)
{
txtBox1.enabled=false;
txtBox1.bgcolor=somecolor;
}
}
}
Please help me on this..
below will change the color of row
if(Condidtion)
{
e.Row.BackColor =somecolor;
}
Your code is specifically selecting one textBox. If you want to apply the condition to all the elements in the row you need to iterate through the controls on the row rather than selecting one and run that condition on each.
It would probably be easier to do this in JavaScript because drawing on a grid and maintaining state between postbacks is more complex.
you can set background color like this
rows[i].BackColor = System.Drawing.Color.RoyalBlue;
or you can set your defined color like bellow
rows[i].BackColor = "#fff23";

datagridview using a datatable with a column href link

I'm trying to figure out how to get a bounded datagridview column in my c# winform project to show up like an href link. The thing is that the link click works but any average user wouldn't realize that they can click the field since it's displayed as a string. I need the field to show up as blue, with underlines, the mouse pointer turns into a hand ...etc.
I was able to accomplish this previously when I was using Datasets with my Datagrid. I went to the designer and selected "Add Column" and added it as a 'DataGridViewLinkColumn". I've recently changed the project to use datatables and I realized that the fields no longer show up as clickable (if I click it does work though).
Any ideal how to accomplish this with relative ease? I've searched and I'm somewhat surprised that I cannot seem to find a simple solution.
Change the type of the cells that are links to be a DataGridViewLinkCell and then handle the click on the cell, like this:
void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
foreach (DataGridViewRow r in dataGridView1.Rows)
{
if (System.Uri.IsWellFormedUriString(r.Cells["Links"].Value.ToString(), UriKind.Absolute))
{
r.Cells["Links"] = new DataGridViewLinkCell();
DataGridViewLinkCell c = r.Cells["Links"] as DataGridViewLinkCell;
}
}
}
// And handle the click too
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex] is DataGridViewLinkCell)
{
System.Diagnostics.Process.Start( dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value as string);
}
}
This might help:
DataGridViewLinkColumn col1 = new DataGridViewLinkColumn();
dataGridView1.Columns.Add(col1);
dataGridView1.Columns[0].Name = "Links";
DataGridViewRow dgvr = new DataGridViewRow();
dgvr.CreateCells(dataGridView1);
DataGridViewCell linkCell = new DataGridViewLinkCell();
linkCell.Value = #"http:\\www.google.com";
dgvr.Cells[0] = linkCell;
dataGridView1.Rows.Add(dgvr);
it creates a col and then a cell of type link.
you can use foreach loops to do this more orderly and faster for more items.
Good Luck!
Take a look at the DataGridViewLinkColumn.LinkBehavior Property. It can be set to AlwaysUnderline.
As for color, simply use the *LinkColor properties on the DataGridViewLinkColumn.
Cheers
You could just colour that column in the datagridview. You could do this in a DataBindingComplete event like so:
private void dataGridView1_DataBindingComplete(object sender,
DataGridViewBindingCompleteEventArgs e)
{
if(this.mydatagridview.Columns["YourLinkColumnName"] != null)
{
this.mydatagridview.Columns["YourLinkColumnName"].DefaultCellStyle.Font = ...
this.mydatagridview.Columns["YourLinkColumnName"].DefaultCellStyle.ForeColor = ...
}
}
You can set the font to be however you like it (ie. underlined, colored, etc.).
Alternatively, you can change the default cell style in the designer if you have the columns premade (not autogeneratedcolumns).

How to check if value from a cell in a column is !=NULL?

I'm trying on gridview updated to check if a cell from a certain column is != NULL ( to check if the user wrote something into the cell)
My problem is I don't know how to get the "x column" value from cell.
inzi irina Please look at this code. don't forget to vote me if this helps you
private void button2_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow dr in dataGridView1.Rows)
{
string lngth = Convert.ToString(dr.Cells[1].Value);
if (lngth.Length > 0)
{
listBox1.Items.Add(dr.Cells[0].Value);
}
}
}
I assume you are approaching through following ways...
You have a footer template and may have a button which saves the values from your footer.
You have an Edit/Update button in grid for each row
For Approach 1(i.e. Footer Template)
You can find like below...
TextBox testing = (TextBox)grd.FooterRow.FindControl("Your Control ID");
For Approach 2 (i.e. using Edit/Update Button)
You can do like below..
Sample Code Behind
protected void grd_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
TextBox testing = (TextBox)grd.Rows[e.RowIndex].FindControl("Your Control ID");
}
Sample HTML
<asp:GridView ID="grd" runat="server" onrowupdating="grd_RowUpdating">
</asp:GridView>

Visible Checkbox only on Gridview's last row?

Is it possible to have a Checkbox that only shows up when Editing the last row of a GridView?
I have tried something like this in the EditItemTemplate:
<asp:CheckBox ID="chkNextDay" runat="server"
ToolTip="Is it a next-day departure?"
Enabled="true"
Checked='<%# DateTime.Parse(Eval("OutHour","{0:d}")).Date >
DateTime.Parse(Eval("InHour","{0:d}")).Date %>'/>
Then on code-behind I tried hiding it for rows other than the last one like this:
protected void grvOutHour_RowEditing(object sender, GridViewEditEventArgs e)
{
GridView grvOutHour = (GridView)this.grvReport.Rows[grvReport.EditIndex].FindControl("grvOutHour");
TextBox txtBox = (TextBox)grvOutHour.Rows[e.NewEditIndex].FindControl("txtEditOutHour");
CheckBox nextDay = (CheckBox)grvOutHour.Rows[e.NewEditIndex].FindControl("chkNextDay");
if (grvOutHour.Rows.Count-1 != e.NewEditIndex)
nextDay.Visible = false;
}
This ALMOST worked, but the checkbox kept showing for all fields, I think because the RowDataBound is called AFTER RowEditing again so it renders the whole thing again :(
Any suggestions?
Thanks,
EtonB.
Use RowDataBound instead...
protected void grvOutHour_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowState == DataControlRowState.Edit)
{
GridView grid = (GridView)sender;
CheckBox nextDay = (CheckBox)e.Row.FindControl("chkNextDay");
nextDay.Visible = (e.Row.RowIndex == (grid.Rows.Count - 1));
}
}
You will need to handle hiding the checkbox in the RowDataBound event.
You'll need to determine what the last row is, and set the checkboxes visible property to true when that condition is true, obviously.
I guess it's more of a hack than an elegant solution, but I would probably just hide the other checkboxes via JavaScript if the condition is true.

Categories