stand on the shoulders of giants

【ASP.NET Step by Step】之十一至十五 Custom Formatting Based Upon Data

Chapter11 Custom Formatting Based Upon Data

1. 绑定数据到控件事件过程

不管是从数据控件或编码填充数据到DataSource属性并调用其DataBind()方法。以下几种事件将触发 

  1. DataBinding事件触发
  2. 数据绑定到数据绑定控件
  3. DataBound事件触发

2. DetailsView如何实现当UnitPrice大于75的行,用粗体,italic字体显示出来?
用DetailsView的DataBound事件

protected void ExpensiveProductsPriceInBoldItalic_DataBound(object sender, EventArgs e)

{
    
// Get the ProductsRow object from the DataItem property
    Northwind.ProductsRow product 
= (Northwind.ProductsRow)((System.Data.DataRowView) ExpensiveProductsPriceInBoldItalic.DataItem).Row;

    
if (!product.IsUnitPriceNull() && product.UnitPrice > 75m)
    {
        
// TODO: Make the UnitPrice text bold and italic
        ExpensiveProductsPriceInBoldItalic.Rows[4].Font.Bold = true;
        ExpensiveProductsPriceInBoldItalic.Rows[
4].Font.Italic = true;
        或者设置CSS的方法
    }
}


注意DataItem属性,见下面的解释。

而对于FormView控件, 因为没有行的集合,是静态HTML,web控件的集合,所以,它的方法是这样的
页面中

asp:FormView ID="LowStockedProductsInRed" runat="server" DataKeyNames="ProductID"
    DataSourceID="ObjectDataSource1" AllowPaging="True" EnableViewState="False">         
    
<ItemTemplate>
        
<b>Product:</b>
        
<asp:Label ID="ProductNameLabel" runat="server" Text='<%# Bind("ProductName") %>'>
        
</asp:Label><br />
        
<b>Units In Stock:</b>
        
<asp:Label ID="UnitsInStockLabel" runat="server" Text='<%# Bind("UnitsInStock") %>'>
        
</asp:Label>
    
</ItemTemplate>
</asp:FormView>


方法是在ItemTempelete中使用FindControl(“controlID”)方法查找控件, 这里要找的ControlID就是 上面的 UnitsInStockLabel

 protected void LowStockedProductsInRed_DataBound(object sender, EventArgs e)
{
        
// Get the ProductsRow object from the DataItem property
        Northwind.ProductsRow product = (Northwind.ProductsRow)((System.Data.DataRowView)LowStockedProductsInRed.DataItem).Row;

        
if (!product.IsUnitsInStockNull() && product.UnitsInStock <= 10)
        {
            Label unitsInStock 
= (Label)LowStockedProductsInRed.FindControl("UnitsInStockLabel"); 

            
if (unitsInStock != null)
            {
                unitsInStock.CssClass 
= "LowUnitsInStockEmphasis";
            }
        }
    }

 

GridView事件触发过程

对于GridView,
     1. DataBinding事件触发 
     2. 数据绑定到数据绑定控件
对于每一行数据..
a.       创建GridViewRow
b.       触发RowCreated 事件
c.       绑定数据到GridViewRow
d.       触发RowDataBound事件
e.       添加GridViewRow到Rows 集合
     3. DataBound事件触发

注意: GridView由各种类型不同的行组成

  • DataRow – a row that is bound to a record from the GridView's DataSource
  • EmptyDataRow – the row displayed if the GridView's DataSource is empty
  • Footer – the footer row; shown if the GridView's ShowFooter property is set to true
  • Header – the header row; shown if the GridView's ShowHeader property is set to true (the default)
  • Pager – for GridView's that implement paging, the row that displays the paging interface
  • Separator – not used for the GridView, but used by the RowType properties for the DataList and Repeater controls, two data Web controls we'll discuss in future tutorials

所以在处理的时候要先进行check

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e){
        
// Make sure we are working with a DataRow
        if (e.Row.RowType == DataControlRowType.DataRow)

            
// Get the ProductsRow object from the DataItem property
            Northwind.ProductsRow product = (Northwind.ProductsRow)((System.Data.DataRowView)e.Row.DataItem).Row;

            
if (!product.IsUnitPriceNull() && product.UnitPrice < 10m)
                e.Row.CssClass 
= "AffordablePriceEmphasis"
}

 

DataItem

Northwind.ProductsRow product=(Northwind.ProductsRow)((System.Data.DataRowView) ExpensiveProductsPriceInBoldItalic.DataItem).Row;
Northwind.ProductsRow product = (Northwind.ProductsRow)((System.Data.DataRowView)e.Row.DataItem).Row;

DetailView和FormView是通过ForView1.DataItem, DetailView1.DataItem得到DataRowView object,
而GridView是通过参数e.Row得到DataRowView object,
DataSource的某条记录绑定到GridViewRow,DataRowView object是对应于这条记录的。它的Row返回这条强类型记录,例如返回ProductsRow

Chapter12 Using TemplateFields in the GridView Control

TemplateFields的应用
     1. 将两个数据合并到一个列中,姓和名字展示在一栏里
     2.
用一个Web控件来展示数据,而不是用一个简单的文本,例如日历控件
     3. 展示数据的元数据,统计每个员工工作多久了
 

后台代码,接受一个EmployeesRow参数,计算到现在的间隔天数

protected string DisplayDaysOnJob(Northwind.EmployeesRow employee)
{
        
if (employee.IsHireDateNull())
        {
            
return "Unknown";
        }
        
else
        {
            TimeSpan ts 
= DateTime.Now.Subtract(employee.HireDate);
            
return ts.Days.ToString("#,###");
        }
}

前台代码,调用前台的函数DisplayDaysOnJob,参数是当前行的EmployeesRow
<asp:TemplateField HeaderText="Days On The Job">
   <ItemTemplate>

     <%# DisplayDaysOnJob((Northwind.EmployeesRow) ((System.Data.DataRowView) Container.DataItem).Row) %>
   <ItemTemplate>
</asp:TemplateField>

Container.DataItem returns a DataRowView object corresponding to the DataSource record bound to the GridViewRow.
Its Row property ((System.Data.DataRowView) Container.DataItem).Row
returns the strongly-typed Northwind.EmployeesRow, which is passed to the DisplayDaysOnJob method.

除了传递一个EmployeesRow的实例,其实我们也可以仅仅传递HireDate的值,使用<%# DisplayDaysOnJob(Eval("HireDate")) %>就可以了。不过呢,Eval方法将返回一个object类型,所以我们就必须要修改DisplayDaysOnJob方法的签名以使其可以接受一个object类型的参数。我们不能将Eval("HireDate")调用的结果隐式的转换成一个DateTime类型,因为Employees表的HireDate字段是允许为空的。因此,我们需要使DisplayDaysOnJob方法可以接受一个object类型的参数,并判断这个参数是不是空值(我们可以使用Convert.IsDBNull(objectToCheck)来完成这个验证工作),然后再进行后面的操作。

对比这个:将discontinued显示为"Yes"/"No", 而不是Checkbox
protected string DisplayDiscontinuedAsYESorNO(bool discontinued)
{
        if (discontinued)        {            return "yes";        }
        else       {            return "no";        }
}
对比上面的相关内容,传递给格式化方法的参数可能是空值,所以我们需要在访问雇员的HiredDate之前对它进行空值检查。这样的检查在这里却是不需要的,因为Discontinued字段永远不会是空值。此外,这也是为什么这个方法接受的是一个布尔值而不是ProductsRow实例或object类型的参数的原因 

1<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
2    <ItemTemplate>
3        <%# DisplayDiscontinuedAsYESorNO((bool) Eval("Discontinued")) %>
4    </ItemTemplate>
5</asp:TemplateField>
6

 

Chapter13 Using the FormView's Templates

这一章没什么意思,在显示一个单独的记录的时候,FormView提供了一种更加复杂的的呈现方式。而不想DetailView和GridView一样都是一个个格子。

Chapter14 Displaying Summary Information in the GridView's Footer

这一章讲了怎么在GridView的Footer里显示统计信息,总量,平均价格等。
统计信息两种方法:
1. SQL语句

1SELECT CategoryID, AVG(UnitPrice), SUM(UnitsInStock), SUM(UnitsOnOrder)
2FROM Products
3WHERE CategoryID = categoryID
4GROUP BY CategoryID


2. 数据绑定之后,计算

 1// 类范围,累积合计的变量……
 2decimal _totalUnitPrice = 0m;
 3int _totalNonNullUnitPriceCount = 0;
 4int _totalUnitsInStock = 0;
 5int _totalUnitsOnOrder = 0;
 6
 7protected void ProductsInCategory_RowDataBound(object sender, GridViewRowEventArgs e)
 8{
 9    if (e.Row.RowType == DataControlRowType.DataRow)
10    {
11        // 通过e.Row.DataItem 属性引用ProductsRow
12        Northwind.ProductsRow product = (Northwind.ProductsRow)((System.Data.DataRowView)e.Row.DataItem).Row;
13
14        // 增加累积合计(如果它们不为NULL的话!)
15        if (!product.IsUnitPriceNull())
16        {
17            _totalUnitPrice += product.UnitPrice;
18            _totalNonNullUnitPriceCount++;
19        }

20
21        if (!product.IsUnitsInStockNull())
22            _totalUnitsInStock += product.UnitsInStock;
23
24        if (!product.IsUnitsOnOrderNull())
25            _totalUnitsOnOrder += product.UnitsOnOrder;
26    }

27}

在页脚中显示统计数据,可以仍然通过RowDataBound事件,只要判断是否是Footer就行了

 1protected void ProductsInCategory_RowDataBound(object sender, GridViewRowEventArgs e)
 2{
 3    if (e.Row.RowType == DataControlRowType.DataRow)
 4    {
 5      //……增加累积合计……
 6    }

 7    else if (e.Row.RowType == DataControlRowType.Footer)
 8    {
 9      // 确定平均单价
10      decimal avgUnitPrice = _totalUnitPrice / (decimal) _totalNonNullUnitPriceCount;
11
12      // 在相应的单元格中显示统计数据
13      e.Row.Cells[1].Text = "Avg.: " + avgUnitPrice.ToString("c");
14      e.Row.Cells[2].Text = "Total: " + _totalUnitsInStock.ToString();
15      e.Row.Cells[3].Text = "Total: " + _totalUnitsOnOrder.ToString();
16    }

17}

 

posted @ 2008-12-21 16:12  DylanWind  阅读(314)  评论(0编辑  收藏  举报