my intention was to switch form an int-represented month value
(as it is in database table)
convert it (to display in GridView) as string(month name)
and return it back to database as int (covert back to original type, int-represented month).
these are the relevant elements in my GridView,
<asp:GridView ID="GV_DaysPerMonth" runat="server" DataSourceID="dsWorkDayPerMonth"
AutoGenerateColumns="False" DataKeyNames="recordID" AllowPaging="True"
CellPadding="4" ForeColor="#333333" GridLines="None" Font-Names="arial" PageSize="12"
OnRowDataBound="GV_DaysPerMonth_RowDataBound"
OnRowEditing="GV_DaysPerMonth_RowEditing"
OnRowUpdating="GV_DaysPerMonth_RowUpdating">
<AlternatingRowStyle BackColor="White" />
<Columns>
<asp:TemplateField HeaderText="חודש" ControlStyle-Width="100" HeaderStyle-Width="120" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<%# Eval("theMonth")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TBX_theMonth" runat="server" Text='<%# Bind("theMonth")%>' />
</EditItemTemplate>
<asp:GridView ID="GV_DaysPerMonth" runat="server" DataSourceID="dsWorkDayPerMonth"
AutoGenerateColumns="False" DataKeyNames="recordID" AllowPaging="True"
CellPadding="4" ForeColor="#333333" GridLines="None" Font-Names="arial" PageSize="12"
OnRowDataBound="GV_DaysPerMonth_RowDataBound"
OnRowEditing="GV_DaysPerMonth_RowEditing"
OnRowUpdating="GV_DaysPerMonth_RowUpdating">
<AlternatingRowStyle BackColor="White" />
<Columns>
<asp:TemplateField HeaderText="Current Month" ControlStyle-Width="100" HeaderStyle-Width="120" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<%# Eval("theMonth")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TBX_theMonth" runat="server" Text='<%# Bind("theMonth")%>' />
</EditItemTemplate>
i was tring using these Helper methods From code Behind
public static CultureInfo ILci = CultureInfo.CreateSpecificCulture("he-IL");
public static string GetMonthName(int mInt)
{
DateTime fullDate = new DateTime(2012, mInt, 2);
string[] tempDayArray = fullDate.ToString("MMMM", ILci).Split(' ');
return tempDayArray[0];
}
public static int GetMonthAsInt(string mStr)
{
return DateTime.ParseExact(mStr, "MMMM", ILci).Month;
to achieve this simple task but had few errors i would like to have an example to how is the right way to achieve it.
i thought it's simple cause displaying int via
<%# manipulation Function( Eval("columnName")) %>
would "just work"
but it got too complicated for me as newb
when trying it with Bind("columnName")
i was wrong by assuming the value was inside Cells[1] when it was actually in Cells[0]
so i do have it in normal mode
and also in Edit mode though not editble but via Label as in view mode instead of a TextBox
protected void GV_DaysPerMonth_RowDataBound(object sender, GridViewRowEventArgs e)
{
RowNum = GV_DaysPerMonth.Rows.Count;
GridViewRow CurRow = e.Row; // Retrieve the current row.
if (CurRow.RowType == DataControlRowType.DataRow)
{
bool isntEmptyMonth = string.IsNullOrEmpty(e.Row.Cells[0].Text) == false;
if (isntEmptyMonth)
{
e.Row.Cells[1].Text = RobCS.RDates.GetMonthName(Convert.ToInt32((e.Row.Cells[0].Text)));
}
}
}
so i think it might be the **missing handler for the edit mode** ?
This is what you would do to get a string Month name from an int:
CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(1);
More info here:
Best way to turn an integer into a month name in c#?
For converting month number into month name in sql server, look here:
Convert Month Number to Month Name Function in SQL
---- EDIT
OK, on RowDataBound, you would want to convert int to string, so it would be something like:
void CustomersGridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
// Display the month name. When you GridView is bound for the first time, you
// will bind the month number, which you can get in e.Row.Cells[1].Text. If
// Cells[1] does not work, try Cells[2], till you get the correct value. The
// convert the int to month name and assign it to the same Cell.
e.Row.Cells[1].Text = GetMonthNameFromInt(e.Row.Cells[1].Text)
}
}
On Row_updating, you want to convert the month name to int again, and then update you dataset (or save to the database)
protected void GridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//Update the values.
GridViewRow row = GridView.Rows[e.RowIndex];
var monthName = ((TextBox)(row.Cells[1].Controls[0])).Text;
var monthNumber = GetMonthNumber(monthName);
// code to update your dataset or database with month number
//Reset the edit index.
GridView.EditIndex = -1;
//Bind data to the GridView control.
BindData();
}
Page class:
private static CultureInfo culture = CultureInfo.CreateSpecificCulture("he-IL");
public static string GetMonthName(string monthNum)
{
return culture.DateTimeFormat.GetMonthName(Convert.ToInt32(monthNum));
}
GridView:
<ItemTemplate>
<%# GetMonthName(Eval("theMonth").ToString())%>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlMonth" runat="server" SelectedValue='<%# Bind("theMonth")%>'>
<asp:ListItem Value="1" Text="תשרי"></ListItem>
etc...
</asp:DropDownList>
</EditItemTemplate>
In your EditTemplate have a DropDownList with ListItems: value="1" Text="תשרי" etc.. so that it's the month number that's passed to your data layer for edits.
Related
My question is how can i insert values into gridviews rows.Basically I have created a gridview in which i bound the footer and i want to insert values in the footer.I have create a 'textboxs','dropdownlist' and 'checkboxes'.I want when i insert value and press "Insert" button then values shown in the gridview and again i insert value and press button then show inserted values in the gridview.Here is my gridview image
and i also want to edit and delete rows as well.Here is my code :
aspx code
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
Height="104px" ShowFooter="True" Width="463px"
AutoGenerateDeleteButton="True" AutoGenerateEditButton="True">
<Columns>
<asp:TemplateField HeaderText="Column Name">
<FooterTemplate>
<asp:TextBox ID="name" runat="server"></asp:TextBox>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Data Type">
<FooterTemplate>
<asp:DropDownList ID="DropDownList2" runat="server">
</asp:DropDownList>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Allow Null">
<FooterTemplate>
<asp:CheckBox ID="allow_null" runat="server" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Primary Key">
<FooterTemplate>
<asp:CheckBox ID="primary" runat="server" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and here is my aspx.cs code :
protected void Button1_Click(object sender, EventArgs e)
{
string name = TextBox1.Text;
string type = DropDownList1.Text;
string allow=Null.Text;
string primary = Primary.Text;
name = ((TextBox)GridView1.FooterRow.FindControl("TextBox2")).Text;
type = ((DropDownList)GridView1.FooterRow.FindControl("DropDownList2")).Text;
allow = ((CheckBox)GridView1.FooterRow.FindControl("allow_null")).Text;
primary = ((CheckBox)GridView1.FooterRow.FindControl("primary")).Text;
}
To use the GridView in this way, with input fields in the footer and a Insert Button that is outside the GridView, you need to make a manual Insert.
I don't know how you perform an Insert using the EF model as I don't currently use it. I guess you could say the "old" way is to use an instance of SqlConnection and SqlCommand. You would use code similar to this inside your Button Click event:
// This is VB. C# is similar, you will have to convert where needed
Using connection As New SqlConnection(connectionString)
Using command As New SqlCommand(queryString, connection)
command.Connection.Open()
command.CommandType = // Typically Text or StoredProcedure as needed
command.Parameters.AddWithValue("#parameter_name1", some_value_1)
command.Parameters.AddWithValue("#parameter_name2", some_value_2)
.
.
.
command.ExecuteNonQuery()
End Using
End Using
queryString is your sql INSERT statement or a stored procedure
command.Parameters is a collection of replaceable parameter in your INSERT statement or Stored Proc.
Addendum
A Gridview is a Data bound control so typically when you use a gridview it's bound to some backing data source. If you are not using a database then you are using some other construct.
If you are using, for example, a DataTable, you would add the new rows and columns to the DataTable using its row and column methods and then rebind the DataTable to the Gridview. You don't add rows and columns directly to a GridView.
See this other SO answer by JonH for an example
In case this helps this is based on the ASPSnippets but modified to be more like you might need. Note that instead of using a DataTable I am using a List where "Row" is a class. It is somewhat a matter of personal preference which one you use. The "Row" class is:
[Serializable]
public class Row
{
public string FieldName { get; set; }
public string FieldType { get; set; }
public Boolean FieldNullible { get; set; }
public Boolean FieldPrimaryKey { get; set; }
}
My names are different from your names. Note that the ASPSnippets sample does not use TemplateFields so I am not. I am not sure if you need to make the "allow"
and/or "primary" fields Boolean so I did not process them in the form. So the ASP.Net form I have is:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
Height="104px" Width="463px"
AutoGenerateDeleteButton="True" AutoGenerateEditButton="True">
<Columns>
<asp:BoundField DataField="FieldName" HeaderText="Name" ItemStyle-Width="120" />
<asp:BoundField DataField="FieldType" HeaderText="Type" ItemStyle-Width="120" />
</Columns>
</asp:GridView>
<br /><asp:Label ID="Label1" runat="server" Text="Name:"></asp:Label>
<br /><asp:TextBox ID="txtName" runat="server" />
<br /><asp:Label ID="Label2" runat="server" Text="Type:"></asp:Label>
<br /><asp:TextBox ID="txtType" runat="server" />
<br /><asp:Button ID="btnAdd" runat="server" Text="Add" OnClick="Insert" />
The code-behind is:
protected void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack)
return;
List<Row> Rows = new List<Row>();
ViewState["Rows"] = Rows;
BindGrid();
}
protected void BindGrid()
{
GridView1.DataSource = (List<Row>)ViewState["Rows"];
GridView1.DataBind();
}
protected void Insert(object sender, EventArgs e)
{
List<Row> Rows = (List < Row >)ViewState["Rows"];
Row r = new Row();
r.FieldName = txtName.Text.Trim();
r.FieldType = txtType.Text.Trim();
Rows.Add(r);
ViewState["Rows"] = Rows;
BindGrid();
txtName.Text = string.Empty;
txtType.Text = string.Empty;
}
One thing I do not like is that the GridView does not show until there is data in it. I assume you can fix that.
This does not implement the editing and deleting.
I want to obtain the new value of a cell in the gridview rowUpdating event:
roles.RoleName = gvRoles.Rows[e.RowIndex].Cells[GetColumnIndexByName(row, "RoleName")].Text;
But the value is empty.
I have checked e.NewValues which is an ordered Dictionary. It contains the new changed value. How do I retrieve the new values for update?
aspx design is:
<asp:GridView ID="gvRoles" DataKeyNames="RoleId" runat="server"
AutoGenerateColumns="False" GridLines="Vertical" CssClass="table
table-striped table-bordered" AutoGenerateEditButton="True"
OnRowCancelingEdit="gvRoles_RowCancelingEdit" OnRowUpdating="gvRoles_RowUpdating"
OnRowEditing="gvRoles_RowEditing">
<Columns>
<asp:BoundField DataField="RoleId" HeaderText="RoleId" ReadOnly="True" />
<asp:BoundField DataField="RoleName" HeaderText="RoleName" ReadOnly="false" />
<asp:BoundField DataField="Role_Description" HeaderText="Role Description" ReadOnly="false" />
<asp:TemplateField HeaderText="RoleStatus">
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" SelectedValue='<%# Bind("Role_Status") %>' >
<asp:ListItem>True</asp:ListItem>
<asp:ListItem>False</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="lblRoleStatus" runat="server"
Text='<%# Bind("Role_Status") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
The easiest way which i found out is to discovered e.NewValues. As I mentioned above it is an ordered dictionary and only i need to manage it.
I need to retrieve new values from this dictionary, which is done i this way.
if (!string.IsNullOrEmpty(e.NewValues["RoleName"].ToString()))
{
roles.RoleName = e.NewValues["RoleName"].ToString();
}
if you have template field it also work for it;
if (!string.IsNullOrEmpty(e.NewValues["Role_Status"].ToString()))
{
roles.Role_Status = Convert.ToBoolean(e.NewValues["Role_Status"].ToString());
}
This is the easiest thing I ever discovered. before that i want just using Find control and casting and then retrieving all lot code.
There is also e.OldValues ordered dictionary. Every one can use it to compare the new value with old ones. If values are same they could notify user to change the value(give new cell value).
GridViewRow row = (GridViewRow)gvRoles.Rows[e.RowIndex];
TextBox textRName = (TextBox)row.Cells[1].Controls[0];
string rname=textRname.Text;
Try This:
protected void gvRoles_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = gvRoles.Rows[e.RowIndex];
TextBox txtBox= (TextBox)(row.Cells[1].Controls[0]);
if(txtBox!=null)
{
String str = txtBox.Text;
}
}
After searching long and hard I found a great article that solved my issue. Take a look at the page load if you are binding on post back then the values get updated before you are able to access them.
Follow this link for more details --> https://taditdash.wordpress.com/2014/06/30/why-gridview-rowupdating-event-is-not-giving-the-updated-values/
The return data type ICollection is a bit tricky. Would have preferred a different data type than a string array but this was simplest direct conversion.
// grabs column headers
String[] keyStrings = new string[e.NewValues.Count];
System.Collections.ICollection keys = e.NewValues.Keys;
keys.CopyTo(keyStrings, 0);
// grabs edit row values
String[] valuesStrings = new string[e.NewValues.Count];
System.Collections.ICollection values = e.NewValues.Values;
values.CopyTo(valuesStrings, 0);
The end result here has two string arrays values and keys which can then be indexed, where the column header has the same index value as the cell value of the edited row.
I have a GridView with some predefined Columns and some generated in code. The idea is that I show Columns according to category, selected by user. I cannot create all Columns and just hide them because I don't know how many Columns I will need. I manage to generate Columns I needed, but the problem starts when I try to remove generated Columns. Situation looks like this:
On first load I see GridView of all categories.
After clicking in ListBox I get result I want. 1 additional Column is created (RemoveAt is not called, because no additional Columns were yet created.).
After clicking in other ListBox Item I still get result I want. Column created last time where deleted and new Column added.
At this point, if I click any other ListBox Item in LicensesCategoriesListBox_SelectedIndexChanged on debugging I see that all of GridView TemplateFields are empty (http://tinypic.com/r/98vdkm/8).
If I comment section gridView.Columns.RemoveAt(i - 1) everything works fine, just Columns keeps generating and generating. Any ideas why all of my TemplateFields, written in my Page becomes empty?
My Page looks like this:
<asp:ListBox ID="licensesCategoriesListBox" runat="server" AutoPostBack="true" OnSelectedIndexChanged="LicensesCategoriesListBox_SelectedIndexChanged" />
<asp:GridView ID="licencesGridView" runat="server" AutoGenerateColumns="False" Caption="Licencijos" DataKeyNames="id" ShowFooter="True">
<Columns>
<asp:TemplateField HeaderText="Pavadinimas">
<EditItemTemplate>
<asp:TextBox ID="licenceNameTextBox" runat="server" MaxLength="50" Text='<%# Bind("name") %>' />
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="newLicenceNameTextBox" runat="server" MaxLength="50" ToolTip="Pavadinimas" />
</FooterTemplate>
<ItemTemplate>
<span><%# Eval("name") %></span>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Kategorija">
<EditItemTemplate>
<asp:DropDownList ID="licenceCategoryDropDownList" runat="server" />
</EditItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="newLicenceCategoryDropDownList" runat="server" ToolTip="Kategorija">
<asp:ListItem Text="Pasirinkite kategoriją:" />
</asp:DropDownList>
</FooterTemplate>
<ItemTemplate>
<span><%# Eval("category") %></span>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code:
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
FillLicences(ref licencesGridView);
}
}
protected void LicensesCategoriesListBox_SelectedIndexChanged(object sender, EventArgs e) {
FillLicences(ref licencesGridView, licensesCategoriesListBox.SelectedValue); /// Value is ID of category.
}
public void FillLicences(ref GridView gridView, string category = "") {
DataTable dataTable;
ushort categoryId;
if (UInt16.TryParse(category, out categoryId)) {
PutAdditionalColumns(ref gridView, categoryId);
dataTable = sqlCommands.GetLicences(categoryId); /// Returns DataTable [name], [category] and additional fields that I add in PutAdditionalColumns method.
} else {
dataTable = sqlCommands.GetAllLicences(); /// Returns DataTable with only [name], [category]
}
gridView.DataSource = dataTable;
gridView.DataBind();
}
public void PutAdditionalColumns(ref GridView gridView, uint category) {
for (ushort i = (ushort)gridView.Columns.Count; i > 2; i--) { /// Removes columns at the end (created for other category)
gridView.Columns.RemoveAt(i - 1);
}
foreach (var pair in sqlCommands.GetLicencesCategoryAttributes(category)) { /// Takes additional field needed.
TemplateField field = new TemplateField(); /// New empty column.
field.AccessibleHeaderText = pair.Key.ToString();
field.HeaderText = pair.Value;
gridView.Columns.Add(field);
}
}
Any ideas why all of my TemplateFields, written in my Page becomes
empty?
Because each of those fields is considered a Column. You're removing them in the code.
If this is your issue, you need some way to seperate columns defined in the aspx to the ones created in the code.
I'd use DataColumn.ExtendedProperties to do this.
Whenever you add a column from code, add a value to ExtendedProperties, showing that it was created in the code.
//...
TemplateField field = new TemplateField(); /// New empty column.
field.AccessibleHeaderText = pair.Key.ToString();
field.HeaderText = pair.Value;
DataColumn ourNewColumn = gridView.Columns.Add(field);
ourNewColumn.ExtendedProperties.Add("CreatedInCode", true);
//...
And then when you come to delete them, only delete them if they have this property set.
//...
if( gridView.Columns[i - 1].ExtendedProperties.ContainsKey("CreatedInCode") ) {
gridView.Columns.RemoveAt(i - 1);
}
//...
I have an ASP Datalist with a nested GridView.
I am trying to display an ASP label for each list item where the gridview has more than 6 rows and keep it hidden for those list items where the gridview has < 6 rows.
Here is the datalist:
<asp:DataList runat="server" id="listResponses" DataKeyField="QuestionID" OnItemDataBound="listResponses_ItemDataBound" Width="100%">
<ItemTemplate>
<div class="question_header">
<p><strong><asp:Label ID="lblOrder" runat="server" Text='<%# Container.ItemIndex + 1 %>'></asp:Label>. <%# DataBinder.Eval(Container.DataItem, "QuestionText") %></strong></p>
</div> <!-- end question_header -->
<asp:GridView runat="server" ID="gridResponses" DataKeyNames="AnswerID" AutoGenerateColumns="False" CssClass="responses" AlternatingRowStyle-BackColor="#f3f4f8">
<Columns>
<asp:BoundField DataField="AnswerTitle" HeaderText="Answer Title" HeaderStyle-ForeColor="#717171" ItemStyle-Width="250px"></asp:BoundField>
<asp:BoundField DataField="Responses" HeaderText="Response Count" HeaderStyle-ForeColor="#717171" HeaderStyle-Width="100px" />
<asp:TemplateField>
<ItemTemplate>
<div class="pbcontainer">
<div class="progressbar"></div>
<asp:HiddenField ID="hiddenValue" runat="server" Value='<%# Eval("Responses") %>' />
</div>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<a><asp:Label runat="server" ID="lblShowResponses" Visible="false"></asp:Label></a>
</ItemTemplate>
</asp:DataList>
The label I am trying to update is lblShowResponses.
The method to populate the datalist:
// populate datalist.
DT = GetData.GetQuestionNameDataList(qid);
listResponses.DataSource = DT;
listResponses.DataBind();
And the gridview is populated as follows:
protected void listResponses_ItemDataBound(object sender, DataListItemEventArgs e)
{
GridView gridResponses = (GridView)e.Item.FindControl("gridResponses");
BindGrid(gridResponses, (int)listResponses.DataKeys[e.Item.ItemIndex], DT.Rows[e.Item.ItemIndex][2].ToString());
}
// Get the question ID from the datalist and parse the parameters to BindGrid
protected void listResponses_ItemDataBound(object sender, DataListItemEventArgs e)
{
GridView gridResponses = (GridView)e.Item.FindControl("gridResponses");
BindGrid(gridResponses, (int)listResponses.DataKeys[e.Item.ItemIndex], DT.Rows[e.Item.ItemIndex][2].ToString());
}
private void BindGrid(GridView GridView, int questionId, string questionType)
{
// get the answerID and title for the current question.
DataTable answersDataTable = new DataTable();
answersDataTable = GetData.GetAnswerResponses(questionId);
DataTable tempResponses = new DataTable();
// checkbox question type - loop through each answer and obtain the number of responses.
for (int answer = 0; answer < answersDataTable.Rows.Count; answer++)
{
// populate tempaory datatable and replace DT with the response count.
string answerID = answersDataTable.Rows[answer][0].ToString();
tempResponses = GetData.getIndividualQuestionResponses(questionId, answerID);
answersDataTable.Rows[answer][2] = tempResponses.Rows[0][0];
}
if (GridView.Rows.Count > 6)
{
for (int x = 6; x < GridView.Rows.Count; x++)
{
GridView.Rows[x].Visible = false;
}
// I want to populate the label here!!!!!!
}
}
How can I update/populate the label lblShowResponses when the gridview contains more than 6 rows?
Not sure if this would help you, pass the DataListItemEventArgs param "e" to the BindGrid method and in the location you want to populate the label and use
(e.Item.FindControl("lblShowResponses") as Label).Text = "Test";
(e.Item.FindControl("lblShowResponses") as Label).Visible = true;
I have a GridView on my aspx page which displays a collection of objects defined by the following class
public class Item
{
public string ItemName{get; set;}
public object ItemValue{get; set;}
}
Then in my aspx markup I have something like this
<asp:GridView ID="MyTable" runat="server">
<Columns>
<asp:BoundField DataField="ItemName" />
<asp:BoundField DataField="ItemValue" />
</Columns>
</asp:GridView>
What I want to know is:
Is there a way to use conditional formatting on the ItemValue field, so that if the object is holding a string it will return the string unchanged, or if it holds a DateTime it will displays as DateTime.ToShortDateString().
Not sure if you can use a BoundField, but if you change it to a TemplateField you could use a formatting function like in this link.
ie something like
<%# FormatDataValue(DataBinder.Eval(Container.DataItem,"ItemValue")) %>
Then in your codebehind, you can add a Protected Function
Protected Function FormatDataValue(val as object) As String
'custom enter code hereformatting goes here
End Function
Or you could do something in the OnRowCreated event of the gridview, like in this link
<asp:GridView ID="ctlGridView" runat="server" OnRowCreated="OnRowCreated" />
this function is conditional formatting based on whether or not the datavalue is null/is a double
protected void OnRowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRowView drv = e.Row.DataItem as DataRowView;
Object ob = drv["ItemValue"];
if (!Convert.IsDBNull(ob) )
{
double dVal = 0f;
if (Double.TryParse(ob.ToString(), out dVal))
{
if (dVal > 3f)
{
TableCell cell = e.Row.Cells[1];
cell.CssClass = "heavyrow";
cell.BackColor = System.Drawing.Color.Orange;
}
}
}
}
}
With BoundField you should modify your Item class.
If you don't want to modify your CodeBehind ther is a sort of trick you can do using a TemplateField:
<asp:GridView ID="MyTable" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="ItemName" HeaderText="Name" />
<asp:TemplateField HeaderText="Value">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# ((Eval("ItemValue") is DateTime) ? ((DateTime)Eval("ItemValue")).ToShortDateString() : Eval("ItemValue")) %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
obviously you can do it for any type of object but maybe your "Text" field would become.. complicated..
by the way.. my CodeBehind for this example was just you class Item and this Page_Load():
protected void Page_Load(object sender, EventArgs e)
{
Item i1 = new Item();
i1.ItemName = "name1";
i1.ItemValue = "foo";
Item i2 = new Item();
i2.ItemName = "name2";
i2.ItemValue = DateTime.Now;
List<Item> list1 = new List<Item>();
list1.Add(i1);
list1.Add(i2);
MyTable.DataSource = list1;
MyTable.DataBind();
}
and the result was correct ;)
i decided with the Paul Rowland solution and more one thing "if (e.Item.DataItem is DataRowView)":
if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
{
if (e.Item.DataItem is DataRowView)
{
DataRowView rowView = (DataRowView)e.Item.DataItem;
String state = rowView[PutYourColumnHere].ToString();
if (state.Equals("PutYourConditionHere"))
{
//your formating, in my case....
e.Item.CssClass = "someClass";
}
}
}
In .NET 2.0 is even easier:
Add this method to code behind: (this example formats a double value as million with 1 digit)
public string EvalAmount(string expression)
{
double? dbl = this.Eval(expression) as double?;
return dbl.HasValue ? string.Format("{0:0.0}", (dbl.Value / 1000000D)) : string.Empty;
}
In the aspx code, use this:
<asp:TemplateField ItemStyle-Width="100px">
<ItemTemplate>
<asp:Label runat="server" Text='<%# EvalAmount("MyAmount") %>'></asp:
</ItemTemplate>
</asp:TemplateField>