protected void ProductsDataSource_Inserting (object sender, ObjectDataSourceMethodEventArgs e) { // Programmatically reference Web controls in the inserting interface... TextBox NewProductName = (TextBox)Products.FooterRow.FindControl("NewProductName"); DropDownList NewCategoryID = (DropDownList)Products.FooterRow.FindControl("NewCategoryID"); DropDownList NewSupplierID = (DropDownList)Products.FooterRow.FindControl("NewSupplierID"); TextBox NewQuantityPerUnit = (TextBox)Products.FooterRow.FindControl("NewQuantityPerUnit"); TextBox NewUnitPrice = (TextBox)Products.FooterRow.FindControl("NewUnitPrice"); TextBox NewUnitsInStock = (TextBox)Products.FooterRow.FindControl("NewUnitsInStock"); TextBox NewUnitsOnOrder = (TextBox)Products.FooterRow.FindControl("NewUnitsOnOrder"); TextBox NewReorderLevel = (TextBox)Products.FooterRow.FindControl("NewReorderLevel"); CheckBox NewDiscontinued = (CheckBox)Products.FooterRow.FindControl("NewDiscontinued"); // Set the ObjectDataSource's InsertParameters values... e.InputParameters["productName"] = NewProductName.Text; e.InputParameters["supplierID"] = Convert.ToInt32(NewSupplierID.SelectedValue); e.InputParameters["categoryID"] = Convert.ToInt32(NewCategoryID.SelectedValue); string quantityPerUnit = null; if (!string.IsNullOrEmpty(NewQuantityPerUnit.Text)) quantityPerUnit = NewQuantityPerUnit.Text; e.InputParameters["quantityPerUnit"] = quantityPerUnit; decimal? unitPrice = null; if (!string.IsNullOrEmpty(NewUnitPrice.Text)) unitPrice = Convert.ToDecimal(NewUnitPrice.Text); e.InputParameters["unitPrice"] = unitPrice; short? unitsInStock = null; if (!string.IsNullOrEmpty(NewUnitsInStock.Text)) unitsInStock = Convert.ToInt16(NewUnitsInStock.Text); e.InputParameters["unitsInStock"] = unitsInStock; short? unitsOnOrder = null; if (!string.IsNullOrEmpty(NewUnitsOnOrder.Text)) unitsOnOrder = Convert.ToInt16(NewUnitsOnOrder.Text); e.InputParameters["unitsOnOrder"] = unitsOnOrder; short? reorderLevel = null; if (!string.IsNullOrEmpty(NewReorderLevel.Text)) reorderLevel = Convert.ToInt16(NewReorderLevel.Text); e.InputParameters["reorderLevel"] = reorderLevel; e.InputParameters["discontinued"] = NewDiscontinued.Checked; }
添加完Inserting事件处理器后,我们就可以通过GridView控件的页脚行添加记录了。开始吧,尝试添加几个产品。
优化并自定义Add操作
一般来说,点击Add按钮后,就将为数据库添加一个新记录。但是没有任何直观的提示反映成功地添加了记录。的确,应该用一个Label Web控件或客户端的消息框提示用户已经成功地添加了产品,我把它作为一个练习留给读者。
本文使用的GridView控件没有对所显示的产品进行任何排序,也未允许最终用户对数据排序。因此,产品依它们在数据库中的次序排序——依主键值顺序。由于每条新添加的记录的ProductID值比上一条的值大,所以,当添加新记录时,它就自然地排到最后一位了。因此,当添加新记录时,你希望自动地转到GridView控件的最后一页。怎么才能办到呢?在RowCommand事件处理器里,调用ProductsDataSource.Insert()方法后,紧接着添加如下一行代码,它说明当数据绑定到GridView后将转到最后一页:
// Indicate that the user needs to be sent to the last page SendUserToLastPage = true;
其中SendUserToLastPage是页面层(page-level)的布尔变量,其初始值为false。在GridView控件的DataBound事件处理器中,如果SendUserToLastPage为false(译注:应该是true),PageIndex属性将使用户转到最后一页。
protected void Products_DataBound(object sender, EventArgs e) { // Send user to last page of data, if needed if (SendUserToLastPage) Products.PageIndex = Products.PageCount - 1; }
为什么我们要在DataBound事件处理器(而不是在RowCommand事件处理器)里设置PageIndex属性呢?如果在RowCommand里设置PageIndex属性的话,它返回的是在添加新记录之前的PageIndex值。在大多数情况下,这样做是没有问题的,但是,如果新添加的记录刚好落到新的一页(译注:比如原本有80个产品,分为8页显示,此时末页的PageIndex为7,当添加第81条记录时,新添加的产品变成第9页第1条记录了,此时末页的PageIndex为8,而不是添加产品前的7),而我们使用RowCommand里设置的PageIndex值话,页面将跳往倒数第2页,而不是我们期望的末页。而DataBound事件是在添加产品且重新绑定以后才发生,我们在DataBound事件处理器里设置的PageIndex值才是真正的末页的PageIndex值。