使用 ItemDataBound 进行高级 DataGrid 格式设置






4.39/5 (24投票s)
2005 年 3 月 14 日
2分钟阅读

229054

4
使用 ItemDataBound 美化您的 DataGrid,使其看起来很酷。
引言
我希望创建的 DataGrid
与打印报告具有相同的功能,并且看起来像我负责替换的某些非常昂贵的报告管理系统,使用 .NET。 最终产品必须将用户的注意力吸引到他们想要的数据上,而不是用多余的字段和细节来迷惑用户。 本文将帮助您入门,使用一些简单的技巧来美化您的 DataGrid
的外观和感觉。
我将向您展示如何
- 为列创建分组
- 突出显示小计和总计
- 根据数据值突出显示单个单元格
SQL 数据和数据库
我使用 Northwind 和 SQL Server 数据库来生成本文的数据,每个产品类别都有一个小计,最后有一个总计。 该代码将适用于任何数据源。 我包含了 SQL 存储过程,供那些有兴趣准确地重现所显示内容的人参考。
我倾向于在数据库端完成几乎所有业务逻辑,并使用 DataGrid
进行显示,因此所有排序和总计都在此处完成。
CREATE PROCEDURE usp_sales_by_cate AS
create table #temp ( Sorty int, CategoryName varchar(50),
ProductName varchar(50), ProductSales real)
-- Get Base Sales
INSERT INTO #temp
SELECT 0, dbo.Categories.CategoryName, dbo.Products.ProductName,
SUM(dbo.[Order Details Extended].ExtendedPrice)
AS ProductSales
FROM dbo.Categories INNER JOIN
dbo.Products INNER JOIN
dbo.Orders INNER JOIN
dbo.[Order Details Extended] ON dbo.Orders.OrderID =
dbo.[Order Details Extended].OrderID ON
dbo.Products.ProductID =
dbo.[Order Details Extended].ProductID ON dbo.Categories.CategoryID =
dbo.Products.CategoryID
WHERE (dbo.Orders.OrderDate BETWEEN '19970101' AND '19971231')
GROUP BY dbo.Categories.CategoryName, dbo.Products.ProductName
ORDER BY dbo.Categories.CategoryName
-- Build SubTotal
INSERT INTO #temp
SELECT 1 , CategoryName, 'SubTotal', sum( ProductSales)
from #temp
group by CategoryName
-- Build Grand Total
INSERT INTO #temp
SELECT 2 , 'XXXXX', 'Grand Total', sum( ProductSales)
from #temp
Where sorty = 0
-- Display Values
SELECT CategoryName, ProductName, ProductSales from #temp
order by CategoryName, Sorty
创建分组
我不希望的是每个类别显示在每一列的第一列中,我只希望在类别更改时才显示该类别。 这为 DataGrid
提供了简洁的外观,允许用户轻松快速地找到项目。
首先,我创建一个公共变量,该变量将在整个页面中工作,更重要的是,每次为 DataGrid
的每一行运行 <Itemdatabound>
时记住某些内容。 在页面 Load
上,它也被预设(这样做我遇到了一些奇怪的问题)。
public class WebForm1 : System.Web.UI.Page
{
public string LastColumn;
..
..
private void Page_Load(object sender, System.EventArgs e)
{
// Set LastColumn to blank.
if (!IsPostBack) LastColumn = "";
然后我使用 <LastColumn>
变量来跟踪写入 DataGrid
的数据的更改。 如果 cell[0]
的单元格值没有改变,则删除单元格的文本并删除单元格的边框
e.Item.Cells[0].Style.Add("BORDER", "none").
忽略 DataGrid
标题
if( ( e.Item.ItemType.ToString()!= "Header"))
{.....
这也可以用于 DataGrid
上的项目、替代项目和页脚,以专门化您的代码。
下面是用于对 DataGrid
的第一列进行分组的完整代码。
private void DataGrid1_ItemDataBound(object sender,
System.Web.UI.WebControls.DataGridItemEventArgs e)
{
//Get the current column 0 text
string CurrentColumn = e.Item.Cells[0].Text;
// Skip Headers
if( ( e.Item.ItemType.ToString()!= "Header"))
{
// Has there been a change
if (CurrentColumn == LastColumn)
{
// No Change in Column 0
//blank and remove boarder
e.Item.Cells[0].Text = "";
e.Item.Cells[0].Style.Add("BORDER", "none");
}
else
{
// this is the first of the series
// set LastColumn to current colums
LastColumn = CurrentColumn;
// Add a little back colour to the Cell[0]
e.Item.Cells[0].BackColor =
System.Drawing.Color.WhiteSmoke;
}
}
突出显示小计和总计
这非常简单,它测试单元格文本是否为“小计”/“总计”,然后将字体、粗体、颜色等设置为您想要的。
// Check to see if its a SubTotal
string MyCol2 = e.Item.Cells[1].Text;
if (MyCol2 == "SubTotal")
{
e.Item.Font.Bold = true;
e.Item.BackColor = Color.DimGray;
e.Item.ForeColor = Color.White;
// blank out Column 0 so its approves
e.Item.Cells[0].Text = "";
e.Item.Cells[0].Style.Add("BORDER", "none");
e.Item.Cells[0].BackColor = Color.Transparent;
}
if (MyCol2 == "Grand Total")
{
e.Item.Font.Bold = true;
e.Item.BackColor = Color.Red;
e.Item.ForeColor = Color.White;
e.Item.Cells[0].Style.Add("BORDER", "none");
e.Item.Cells[0].BackColor = Color.Transparent;
}
突出显示单个单元格
我经常使用它来以红色显示负值(会计师喜欢的方式)。 我发现将字符串解析为数字可能会产生一些奇怪的错误,所以我通常将其包装在 try
和 catch
中,以忽略可能出现的任何错误。
// Make some items standout if below 5000 in sales
string MyStr = e.Item.Cells[2].Text;
try
{
double MyValue = double.Parse(MyStr);
if (MyValue < 5000 )
{
e.Item.Cells[2].ForeColor = Color.Red;
e.Item.Cells[2].Font.Bold = true;
}
}
catch(Exception)
{
// its not a valid number
}
这就是全部内容,希望您喜欢,如果您有任何问题或疑问,请提出。
历史
V10.0 2005年3月11日