65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.39/5 (24投票s)

2005 年 3 月 14 日

2分钟阅读

viewsIcon

229054

downloadIcon

4

使用 ItemDataBound 美化您的 DataGrid,使其看起来很酷。

Sample image

引言

我希望创建的 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;
}

突出显示单个单元格

我经常使用它来以红色显示负值(会计师喜欢的方式)。 我发现将字符串解析为数字可能会产生一些奇怪的错误,所以我通常将其包装在 trycatch 中,以忽略可能出现的任何错误。

// 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日

© . All rights reserved.