Every now and then, someone requests that a html table with should somehow be customised based on data shown, for eg. each row should have different background color for each „Status” column in data-item. In my knowledge there is no easy way of doing it declarative in ASP.NET using standard controls for eg. by data binding RowStyle-CssClass, strange that MS did never thought about such a simple feature.
Here an example how you can add support for row-by-row styling, after you select an appropriate column, just add css style for each possible data value.
/* Copyright 2007 Janusz Skonieczny
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Created by: Janusz Skonieczny 2006-06-02
*
* Last changes made by:
* $Id: $
*/
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using Qualent.Common;
namespace WooYek.Web.UI.WebControls {
/// <summary>
/// A simple <see cref="GridView"/> override that adds support to declarative chose a data item column values
/// that will be used as a CssClass for each <see cref="GridViewRow"/>.
/// </summary>
[ToolboxData("<{0}:StyledGridView runat=server></{0}:StyledGridView>")]
public class StyledGridView : GridView {
///<summary>
///Raises the <see cref="E:System.Web.UI.WebControls.GridView.RowDataBound"></see> event.
///</summary>
///
///<param name="e">A <see cref="T:System.Web.UI.WebControls.GridViewRowEventArgs"></see> that contains event data.</param>
protected override void OnRowDataBound(GridViewRowEventArgs e) {
base.OnRowDataBound(e);
FillCssClass(e);
}
/// <summary>
///
/// </summary>
/// <param name="e"></param>
private void FillCssClass(GridViewRowEventArgs e) {
string cssClassColumnName = CssClassColumnName;
if (!String.IsNullOrEmpty(cssClassColumnName) && e.Row.RowType == DataControlRowType.DataRow) {
object dataItem = e.Row.DataItem;
Guard.NotNull(dataItem, "dataItem", "Given dataItem is null");
object eval = DataBinder.Eval(dataItem, cssClassColumnName);
if (eval == null) {
throw new InvalidOperationException("There is no data in dataItem for member " + cssClassColumnName);
}
e.Row.CssClass = eval.ToString();
}
}
public string CssClassColumnName {
get { return (string) ViewState["CssClassColumnName"]; }
set { ViewState["CssClassColumnName"] = value; }
}
}
}
An exmaple of page (control is registered in web.config)
<%@ Page Language="C#" MasterPageFile="~/Default.master" AutoEventWireup="true" CodeFile="CustomerList.aspx.cs" Inherits="web_CusomerList" Title="Customer List" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<asp:SqlDataSource ID="SqlDataSource1" runat="server" CancelSelectOnNullParameter="false" ConnectionString="<%$ ConnectionStrings:Default %>" SelectCommand="SELECT * FROM [vCustomer]">
</asp:SqlDataSource>
<wc:StyledGridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="CustomerId" DataSourceID="SqlDataSource1" CssClassColumnName="CustomerStatusName">
<Columns>
<asp:BoundField DataField="CustomerId" HeaderText="ID" ReadOnly="True" SortExpression="CustomerId" />
<asp:HyperLinkField DataTextField="CustomerName" HeaderText="Nazwa" SortExpression="CustomerName" DataNavigateUrlFields="CustomerId" DataNavigateUrlFormatString="CustomerDetails.aspx?CustomerId={0}" />
<asp:BoundField DataField="CustomerStatusName" HeaderText="Status" ReadOnly="True" SortExpression="CustomerStatusName" />
</Columns>
</wc:StyledGridView>
</asp:Content>
And here an example of CSS class you could use.
tr.StatusNew {
background-color: #efffb5;
}
tr.StatusArchive {
background-color: #ccff33;
}