在GridView的页脚中显示统计信息
在GridView的页脚中显示统计信息(首先要做的工作是把GridView的ShowFooter属性设为true,并更改其style)
利用2种方法来统计数据:
1. SQL查询(统计的是全部项)
SELECT CategoryID, AVG(UnitPrice), SUM(UnitsInStock), SUM(UnitsOnOrder)
FROM Products
WHERE CategoryID = categoryID
GROUP BY CategoryID
2.基于GridView的RowDataBound事件处理方法(它会在每一行绑定到GridView的时候被触发,但在加入Rows之前,可以使用e访问)
要在页脚的特定单元格中显示文本,可以使用use e.Row.Cells[index].Text = value,单元格的索引是从0开始的。代码如下:
protected void ProductsInCategory_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//……增加累积合计……
}
else if (e.Row.RowType == DataControlRowType.Footer)
{
// 确定平均单价
decimal avgUnitPrice = _totalUnitPrice / (decimal) _totalNonNullUnitPriceCount;
// 在相应的单元格中显示统计数据,无需数据绑定
e.Row.Cells[1].Text = "Avg.: " + avgUnitPrice.ToString("c"); //格式化为货币格式
e.Row.Cells[2].Text = "Total: " + _totalUnitsInStock.ToString();
e.Row.Cells[3].Text = "Total: " + _totalUnitsOnOrder.ToString();
}
}
使用此种方法由于footer是在最后加入Rows的,所以可以统计出数据,但是如果分页的话,统计出的数据只代表当前页而非所有项。如下图:

统计的数据是当前页而非全部
结束语:数据表达的方式有多种,可以看具体情况选择。下面的语句中还包含了一些东西,还要进一步理解:Northwind.ProductsRow product = (Northwind.ProductsRow)((System.Data.DataRowView)e.Row.DataItem).Row;
概述插入、更新和删除数据
在整个站点中加入一个新内容的文件夹(下面包含很多页面),要使这些它在站点导航中显示,可以将建立的用户控件(ascx文件)拖入文件下的默认页面中(default.aspx),并修改站点导航模板(sitemap文件),将新建页面节点加入其中。
使用数据源配置向导来配置ObjectDataSource的一个影响是Visual Studio设置了OldValuesParameterFormatString属性为original_{0} 。这个属性值用来包含数据被编辑时的原始值,它在下面两种情况下非常有用:
1.如果,当编辑一条记录时,用户可以修改主键的值。在这种情况下,新的主键的值和原始的主键值都需要提供,这样具有这个原始主键值的数据库记录才可以被找到然后才能将它的值更新。
2.当使用开放式并发。开放式并发是为了保证同时操作的用户不至于覆盖另一个用户所做更改的一种技巧.这个OldValuesParameterFormatString属性指明了隐含对象的更新和删除方法中对应原始值的输入参数的名称。OldValuesParameterFormatString属性设置为除了默认值({0})以外的其它任何的值,都将在数据Web控件尝试调用ObjectDataSource的Update()或Delete()方法时引发一个错误,因为ObjectDataSource将尝试将这些原始值参数与UpdateParameters或DeleteParameters一起传入。如果你忘记了从ObjectDataSource里删除OldValuesParameterFormatString属性。指定了OldValuesParameterFormatString属性的话,该ObjectDataSource会试图向DeleteProduct方法一并传入productID和original_ProductID输入参数,然而,DeleteProduct方法只能接受一个输入参数,导致异常。删除OldValuesParameterFormatString属性(或设置它为{0})指示ObjectDataSource不要试图传入这个原始值的输入参数。一个字段间约束也会阻止对数据(这里指产品)的删除,导致异常。在一个真实的应用程序中我们需要的是下面任一措施:(a) 通过另外一个页面管理order details信息.(b) 在DeleteProduct方法里增加包含删除指定产品的订单明细的逻辑.(c) 修改TableAdapter所使用的SQL语句,包含对指定产品的订单明细的删除.
通过它的职能标记绑定GridView到ObjectDataSource有下面两点的好处:
1. 绑定列和CheckBox列被自动地添加,对应ObjectDataSource返回的每一个字段。而且,这些绑定列和CheckBox列的属性已经被设置,基于隐含字段的元数据。例如ProductID、CategoryName和SupplierName列(其它表的字段,BLL下ProductsBLL.cs提供的操作函数只针对本表,不对其它表操作,SQL语句{INSERT INTO [Products] ([ProductName], [SupplierID], [CategoryID], [QuantityPerUnit], [UnitPrice], [UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued]) VALUES (@ProductName, @SupplierID, @CategoryID, @QuantityPerUnit, @UnitPrice, @UnitsInStock, @UnitsOnOrder, @ReorderLevel, @Discontinued);SELECT SCOPE_IDENTITY()},故设置ReadOnly属性为true)在ProductsDataTable里被标记为只读,因此它们在编辑时也是不可更新的。为了实现这一点,这些绑定列的ReadOnly属性设置为true 。
2. DataKeyNames属性被赋值为隐含对象的主键。这是在使用GridView来编辑或删除数据的要点,因为这个属性象指出了标识唯一记录的那个字段(或是一组字段)。(DataKeyNames属性让每一行关联一个或多个数据字段, 经常用于唯一标识GridView行. SelectedValue属性返回选中行的DataKeyNames中的第一个数据字段的值, SelectedDataKey返回选中行的DataKey对象, 它包含了该行的所有指定数据主键字段的值.)
在GridView中,当最终用户点击特定一行的编辑按钮时,引发一次回传并且GridView执行以下步骤:
1. GridView的EditItemIndex属性被赋值为当前点击编辑按钮的行的索引。
2. 通过调用它的Select()方法,GridView重新绑定自己到ObjectDataSource。
3. 与EditItemIndex相匹配的行呈现为编辑模式。在此模式下,编辑按钮替换为保存和取消按钮,并且那些ReadOnly属性为False的绑定列呈现为TextBox服务器控件,这些TextBox的Text属性被赋值为相应的数据字段的值。
到这里HTML标记被返回到浏览器,允许最终用户可以修改行数据。当用户点击保存按钮,再次发生一次回传,并且GridView执行以下几个步骤:
1. ObjectDataSource的UpdateParameters的值被赋值为最终用户在GridView的编辑界面输入的值。
2. 调用ObjectDataSource的Update()方法,更新指定的记录。
3. 通过调用它的Select()方法,GridView重新绑定自己到ObjectDataSource。
当最终用户点击某一特定行的删除按钮时,引发一次回传并且GridView执行以下步骤:
1. 对ObjectDataSource的DeleteParameters赋值
2. 调用ObjectDataSource的Delete()方法,删除指定的记录
3. 通过调用它的Select()方法GridView重新绑定到ObjectDataSource
赋值到DeleteParameters的值是点击删除按钮这一行的DataKeyNames字段的值。因此正确地设置GridView的DataKeyNames属性是至关重要的。如果缺少了这个,DeleteParameters将在第1步被赋上一个null值,从而在第2步中将不会导致删除任何记录。
Scott Mitchell指出:DetailsView的CurrentMode 属性指示当前显示的界面并可以被设置为下面几个值之一:Edit、Insert或ReadOnly 。DefaultMode属性则指示DetailsView在完成一次编辑或插入之后显示的模式,这在需要让DetailsView保持编辑或插入模式不变时是很有用的。
确实DefaultMode属性则指示DetailsView在完成一次编辑或插入之后显示的模式,比如事先更改DetailsView的DefaultMode为edit的话,那么网页加载后DetailsView将会以edit的模式出现,如下图:

但"CurrentMode 属性指示当前显示的界面并可以被设置为下面几个值之一:Edit、Insert或ReadOnly 。"如何理解?当更改其值(赋值)时,编译器提示该属性为只读,那么如何来利用该属性呢?