当用户点击一个Button(位于FormView内部EdiTemplate)时,页面会回发,FormView的ItemCommand event被激发.我们可以为这个事件创建一个event handler ,用来在Button 被点击时执行自定义代码。注意:任何时候FormView里的任何Button, LinkButton, 或 ImageButton被点击时,ItemCommand 事件都会被激发.这意味着当用户在FormView里从一个页面跳到另一个页面时,ItemCommand 事件会被激发.当用户点击一个支持inserting, updating, 或 deleting的FormView里的New, Edit, 或 Delete 时,ItemCommand 事件会被激发。(要熟悉FormView的构造) 既然无论点击什么button时, ItemCommand 都会被激发,那么在event handler里我们需要判断是“Discontinue All Products” Button 被点击了还是其它的button.为了达到这个目的,可以通过设置Button 的CommandName来识别. 当Button 被点击后,CommandName 的值被传到ItemCommand 的event handler,我们通过这个值来判断被点击的button是否是“Discontinue All Products” Button。设置“Discontinue All Products” Button的CommandName 为“DiscontinueProducts”。
C#
protected void Suppliers_ItemCommand(object sender, FormViewCommandEventArgs e)
{
if (e.CommandName.CompareTo("DiscontinueProducts") == 0)
{
// The "Discontinue All Products" Button was clicked.
// Invoke the ProductsBLL.DiscontinueAllProductsForSupplier(supplierID) method
// First, get the SupplierID selected in the FormView
int supplierID = (int)Suppliers.SelectedValue;
// Next, create an instance of the ProductsBLL class
ProductsBLL productInfo = new ProductsBLL(); //此处为何不使用Adapter?
// Finally, invoke the DiscontinueAllProductsForSupplier(supplierID) method
productInfo.DiscontinueAllProductsForSupplier(supplierID);
}
}
GridView, DetailsView, 和FormView都可以包含Buttons, LinkButtons, 或ImageButtons.这些button被点击时,页面回发,并激发FormView 和DetailsView 的ItemCommand 事件,GridView的RowCommand 事件.除了可以执行本身内置的功能外,还可以使用执行自定义代码的button.为了达到这个目的,需要为ItemCommand 或 RowCommand 创建一个event handler(事件处理程序). 在这个event handler 里我们首先检查CommandName 的值来判断哪个button被点击了,然后执行相应的自定义代码.
注意:任何时候FormView里的任何Button,LinkButton, 或 ImageButton被点击时,ItemCommand 事件都会被激发.这意味着当用户在FormView里从一个页面跳到另一个页面时,ItemCommand 事件会被激发.当用户点击一个支持inserting, updating, 或 deleting的FormView里的New,Edit, 或 Delete 时,ItemCommand 事件会被激发. 以下为自定义功能实现的代码段:
C#
protected void SuppliersProducts_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.CompareTo("IncreasePrice") == 0 ||e.CommandName.CompareTo("DecreasePrice") == 0)
{
// The Increase Price or Decrease Price Button has been clicked
// Determine the ID of the product whose price was adjusted
int productID =(int)SuppliersProducts.DataKeys[Convert.ToInt32(e.CommandArgument)].Value;
/*e.CommandArgument是用来获取button所在row的rowIndex。此时e.CommandName为Button所设置的CommandName。DataKeys获取一个 DataKey(数据绑定控件中某个记录的一个或多个主键字段) 对象集合,这些对象表示 GridView 控件中的每一行的数据键值。类CommandEventArgs有两个公共属性,CommandName(用来获取命令的名称)和CommandArgument(用来获取命令的参数)*/
// Determine how much to adjust the price decimal percentageAdjust;
if (e.CommandName.CompareTo("IncreasePrice") == 0)
percentageAdjust = 1.1M;
/*从Double类型到Decimal的显示转换(整型可以隐式转换为Decimal类型,不必在后面加M,详情见下方的MSDN查阅)*/
else
percentageAdjust = 0.9M;
// Adjust the price
ProductsBLL productInfo = new ProductsBLL();
productInfo.UpdateProduct(percentageAdjust, productID);
}
}
为了判断被点击“Price +10%” or “Price -10%” button 的那一行的ProductID ,我们需要用到GridView的DataKeys集合.这个集合包含了GridView 的行的所有值.由于GridView在绑定到ObjectDataSource时,DataKeyNames 被Visual Studio设置为ProductID ,DataKeys(rowIndex).Value 提供了指定rowIndex的ProductID .ButtonField 会将被点击的button所在row 的rowIndex 自动传到e.CommandArgument 参数里.(e.CommandName为当前点击的Button的CommandName,此处Button为当前行的一个ButtonField)因此,用Convert.ToInt32(SuppliersProducts.DataKeys(Convert.ToInt32(e.CommandArgument)).Value)来获取被点击“Price +10%” or “Price -10%” button的行的ProductID . 和“Discontinue All Products” button里一样,如果你禁用了GridView的view state属性,每次postback时GridView 都会重新绑定。 如果你不这么做,你需要手动再次绑定。
注意:GridView (和DetailsView)同样可以将Buttons,LinkButtons或ImageButtons 加到TemplateFields里.和BoundField一样,这些Button被点击时会产生回发,触发GridView的RowCommand 事件.当添加button到TemplateField里时,button的CommandArgument不会像使用ButtonFields一样,被自动设置为row 的index .如果你需要在RowCommand的event handler里判断点击的button所在行的index ,你需要在TemplateField的页面代码里使用以下代码来设置button的CommandArgument 属性:
<asp:Button runat="server" ... CommandArgument='<%# CType(Container, GridViewRow).RowIndex %>' /> 。
以下为查阅MSDN中的相关内容:
GridView.DataKeys 属性获取一个 DataKey 对象集合,这些对象表示 GridView 控件中的每一行的数据键值。
属性值
一个 DataKeyArray,其中包含 GridView 控件中每一行的数据键。
备注
当设置了 DataKeyNames 属性时,GridView 控件自动为该控件中的每一行创建一个 DataKey 对象。DataKey 对象包含在DataKeyNames 属性中的指定的字段的值。DataKey 对象随后被添加到控件的 DataKeys 集合中。使用 DataKeys 属性检索 GridView 控件中特定数据行的 DataKey 对象。
注意
可使用 SelectedDataKey 属性检索当前选中行的 DataKey 对象。还可以使用 SelectedValue 属性直接检索当前选中行的数据键值。DataKeyArray 类表示DataKey 对象的集合。无法继承此类。
备注
DataKeyArray 类用于存储和管理 DataKey 对象的集合。DataKey 对象表示数据绑定控件中某个记录的主键。通常情况下,显示多个记录的数据绑定控件(如 GridView 控件)使用 DataKeyArray 对象来存储该控件中显示的记录的DataKey 对象。
DataKeyArray 类支持多种访问集合中的项的方法:使用 Item 索引器直接从集合中从零开始的特定索引位置检索 DataKey 对象。使用 GetEnumerator 方法检索可用于循环访问集合的枚举数。使用 CopyTo 方法将集合中的项复制到数组,然后可使用该数组访问集合中的项。若要确定集合中的总项数,请使用 Count 属性。
DataKey 类 表示数据绑定控件中某个记录的一个或多个主键字段。 DataKey 类用于表示数据绑定控件中某个记录的主键。记录的主键可以由数据源中的一个或多个字段组成。尽管 DataKey 类不是集合,但它可以存储多个键字段值。当调用 DataKey 类的某个构造函数时,将填充键字段值。可以通过以下方法从 DataKey 对象中检索键字段值:使用 DataKey.Item(Int32) 属性检索 DataKey 对象中特定索引位置的键字段值。使用 DataKey.Item(String) 属性检索特定字段的键字段值。使用 Value 属性检索 DataKey 对象中索引 0 位置的键字段值。当主键只包含一个字段时,此属性常用作检索记录键值的快捷方式。使用 Values 属性创建可用于循环访问键字段值的 IOrderedDictionary 对象。通常,当设置了数据绑定控件的 DataKeyNames 属性时,控件自动生成 DataKey 对象。DataKey 对象包含DataKeyNames 属性中指定的一个或多个键字段的值。一次显示一个记录的数据绑定控件(如 DetailsView 或 FormView)通常在它的 DataKey 属性中存储所显示的当前记录的 DataKey 对象。一次显示多个记录的数据绑定控件(如GridView)通常在 DataKeyArray 集合中存储它的每个记录的 DataKey 对象。然后,DataKeyArray 集合将存储在控件的 DataKeys 属性中。
关于decimal类型(C# 参考)
decimal关键字表示 128 位数据类型。同浮点型相比,decimal类型具有更高的精度和更小的范围,这使它适合于财务和货币计算。decimal 类型的大致范围和精度如下表所示。
类型 大致范围 精度 .NET Framework 类型
decimal ±1.0 × 10e−28至±7.9 × 10e28 28到29位有效位 System.Decimal
标识符
如果希望实数被视为 decimal 类型,请使用后缀 m 或 M,例如:decimal myMoney = 300.5m;如果没有后缀 m,数字将被视为 double 类型,从而导致编译器错误。
转换
整型被隐式转换为 decimal,其计算结果为 decimal。因此,可以用整数初始化十进制变量而不使用后缀,如下所示:
decimal myMoney = 300;
在浮点型和 decimal 类型之间不存在隐式转换;因此,必须使用强制转换在这两种类型之间进行转换。例如:decimal myMoney = 99.9m; double x = (double)myMoney; myMoney = (decimal)x;
还可以在同一表达式中混合使用 decimal 和数值整型。但是,不进行强制转换就混合使用 decimal 和浮点型将导致编译错误。