在ASP.NET 2.0中操作数据之二十二:为删除数据添加客户端确认

导言

  在前面一些教程中,我们已经看到如何使用应用程序框架,ObjectDataSource,以及那些提供增、改、删功能的数据Web控件。在我们已经实现的删除数据的界面中,包含一个删除按钮,当点击它的时候,会导致数据回传以及调用ObjectDataSource的Delete()方法。然后Delete()方法会调用对应业务逻辑层中的方法,再进入数据访问层,直至调用最终操作数据库的DELETE语句。

  虽然这个界面已经能够让用户通过GridView,DetailsView,或者FormView控件来删除记录,但是在用户点击删除按钮的时候,它缺少一些提示信息。如果用户本想点击编辑按钮,但是不小心点击了删除按钮,那么原本会更新的记录将会被删除。为了避免此类事情发生,在这篇教程里面,我们将为点击删除按钮的时候,添加一个能在客户端显示提醒的窗口。

  JavaScript的confirm(string)方法将在一个模式窗口中显示那些作为string参数传进来的文本,这个窗口将会显示两个按钮-确定(OK)和取消(Cancel)。(见图1)confirm(string)方法将根据点击不同的按钮来返回一个布尔类型值。(返回true,如果点击了确定(OK),返回false如果点击了取消(Cancel))

图1:JavaScript的confirm(string)方法显示一个模式的,客户端的窗口

  在一个表单的提交过程中,如果从客户端的事件处理器返回一个false值,那么这个表单将取消提交。使用这种特性,我们可以在这个删除按钮的客户端事件处理器 onClick中,调用confirm(“你确定要删除这个产品吗?”),让它返回一个布尔值。如果用户点击了取消,confirm(string)将返回false,因此会取消表单的提交。在没有回传的前提下,这个已经点击了删除按钮的产品并没有被删除。相反,如果在确认窗口中用户点击了确定,回传将会继续而且这个产品将会被删除。参考 使用JavaScript的confirm()方法控制表单提交 来获取这方面的更多信息。

  在添加这些有用的客户端脚本时候,使用模版和使用一个CommandField相比,将会有一些细微的差别。因此,在这篇教程中,我们将同时考察FormView和GridView的例子。

  注意:正如这篇教程中讨论到的,使用客户端确认技术时候,我们假设用户的浏览器支持JavaScript并且已经启用了JavaScript支持。如果这其中的任何一个假设不能满足,那么点击删除按钮的时候将会立即进行回传而不会显示一个确认窗口。

第一步:新建一个支持删除的FormView

  首先在EditInsertDelete目录下面,创建ConfirmationOnDelete.aspx页面,并添加一个FormView控件,然后给这个控件绑定一个ObjectDataSource,这个数据源控件将从ProductsBLL类的GetProducts()方法获取产品信息。同时给它的Delete()方法绑定指向ProductsBLL类的DeleteProduct(productID)方法。确保INSERT和UPDATE标签的下拉框中为(None)。最后,在FormView的属性窗口中勾上Enable Paging多选框。

  通过这些步骤,创建了一个以下语句声明的ObjectDataSource:

<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
  DeleteMethod="DeleteProduct" OldValuesParameterFormatString="original_{0}"
  SelectMethod="GetProducts" TypeName="ProductsBLL">
  <DeleteParameters>
    <asp:Parameter Name="productID" Type="Int32" />
  </DeleteParameters>
</asp:ObjectDataSource>

  因为在我们前面的例子中没有使用到optimistic concurrency,可以把OldValuesParameterFormatString属性删掉。

  因为这个FormView已经被绑定到一个仅仅支持删除的ObjectDataSource控件,在ItemTemplate中我们只要提供删除按钮,而不需要新建和更新按钮。而在FormView的声明标记中,可以删掉我们不再需要的EditItemTemplate以及InsertItemTemplate。稍微花点时间定制一下ItemTemplate以便只显示一组产品属性。我已经定制好了,用<h3>样式显示产品的名字作为标题,接下来是供应商和分类的名字(以及删除按钮)。

<asp:FormView ID="FormView1" AllowPaging="True" DataKeyNames="ProductID"
  DataSourceID="ObjectDataSource1" runat="server">
  <ItemTemplate>
    <h3><i><%# Eval("ProductName") %></i></h3>
    <b>Category:</b>
    <asp:Label ID="CategoryNameLabel" runat="server"
      Text='<%# Eval("CategoryName") %>'>
    </asp:Label><br />
    <b>Supplier:</b>
    <asp:Label ID="SupplierNameLabel" runat="server"
      Text='<%# Eval("SupplierName") %>'>
    </asp:Label><br />
    <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
      CommandName="Delete" Text="Delete">
    </asp:LinkButton>
  </ItemTemplate>
</asp:FormView>

  做了这些变化之后,我们已经有了一个功能完善的页面,可以允许用户显示每个产品,以及通过简单地点击按钮来删除某个产品。图2显示了在浏览器中访问我们上面所完成的例子的截图。

图2:FormView控件显示一个产品

第二步:在删除按钮的客户端onclick事件中调用confirm(string)方法

  在创建FormView之后,最后的步骤是配置这个删除按钮,使得用户点击它的时候,JavaScript的confirm(string)方法会被调用。可以通过使用OnClientClick这个属性来为Button,LinkButton,ImageButton的客户端onclick事件添加客户端脚本,这个属性是ASP.NET 2.0新引入的。因为我们想让confirm(string)方法有返回值,可以简单地设置属性值为:return confirm(‘你确定要删除这个产品吗?')。

  修改之后这个删除按钮的声明语法应该如下所述:3给出了这个提示操作的截图。点击这个删除按钮激活确认窗口的显示。如果用户选择取消,回传将被取消,产品也不会被删除。相反,用户选择确定,回传继续,ObjectDataSource的Delete()方法被调用,最后数据库中相应的记录也会被删除。

<asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
  CommandName="Delete" Text="Delete"
  OnClientClick="return confirm('Are you certain you want to delete this product?');">
</asp:LinkButton>

  仅仅只需要这么多!

  注意:传入confirm(string) JavaScript方法的字符串用单引号进行标记(而不是双引号)。在JavaScript中,标记字符串可以是单引号也可以是双引号。我们这里使用单引号是为了确保不影响OnClientClick这个属性本身的双引号标记。

图3:当点击删除按钮时候显示一个确认窗口

第三步:在一个CommandField中为删除按钮设置OnClientClick属性

  在模板中直接使用Button,LinkButton,或者ImageButton的时候,可以直接为它的OnClientClick属性设置确认窗口并返回confirm(string) JavaScript的返回值。然而,CommandField是在GridView或者DetailsView上内置的一些删除按钮,而且它们本身不具有OnClientClick属性可以设置声明。相反,我们必须要在处理GridView或者DetailsView,它们适当的DataBound事件的代码中,引用这个删除按钮,然后在那里设置它的OnClientClick属性。

  注意:当我们在适当的DataBound事件处理器中设置删除按钮的OnClientClick属性时候,我们已经有权限访问当前绑定的数据。这意味着我们可以扩展确认信息,并包含具体记录的详细信息,比如,“你确定要删除这个Chai产品吗?“这些定制也可以在模板的数据绑定的语法中实现。

  为了实践在一个CommandField中设置删除按钮的OnClientClick属性,我们在页面上添加一个GridView。配置这个GridView使用FormView一样的ObjectDataSource控件。同时,限制GridView的BoundFields属性只包括产品名称,分类和供应商。最后,在GridView的属性窗口中勾上Enable Deleting的多选框。这样会在GridView的ColumnCollection的集合中添加一列CommandField,并且它的ShowDeleteButton属性会设置成true。

  做了这些改变后,你的GridView的声明标记应该如下所示:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
  DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
  <Columns>
    <asp:CommandField ShowDeleteButton="True" />
    <asp:BoundField DataField="ProductName" HeaderText="Product"
      SortExpression="ProductName" />
    <asp:BoundField DataField="CategoryName" HeaderText="Category" ReadOnly="True"
      SortExpression="CategoryName" />
    <asp:BoundField DataField="SupplierName" HeaderText="Supplier" ReadOnly="True"
      SortExpression="SupplierName" />
  </Columns>
</asp:GridView>

  这个CommandField包含一个删除LinkButton实例,并且可以在GridView的RowDataBound事件处理器中被访问。一旦被引用,我们就可以相应地设置它的OnClientClick属性。通过下面的代码来新建一个RowDataBound事件的处理器:

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
  if (e.Row.RowType == DataControlRowType.DataRow)
  {
    // reference the Delete LinkButton
    LinkButton db = (LinkButton)e.Row.Cells[0].Controls[0];

    // Get information about the product bound to the row
    Northwind.ProductsRow product =
      (Northwind.ProductsRow) ((System.Data.DataRowView) e.Row.DataItem).Row;

    db.OnClientClick = string.Format(
      "return confirm('Are you certain you want to delete the {0} product?');",
      product.ProductName.Replace("'", @"\'"));
  }
}

  这个事件处理器将在代码中绑定数据和引用删除按钮的时候被调用。总的来说,使用了以下模式:
ButtonType是被CommandField使用的一种按钮类型,可以是Button,LinkButton,或者ImageButton。默认情况下,CommandField使用LinkButton,但也可以通过CommandField的ButtonType属性来定制。CommandFieldIndex是CommandField在GridView中Columns集合中的原始索引,而controlIndex是删除按钮在CommandField的Controls集合中的索引。controlIndex的值由按钮在CommandField中和其他按钮的相对位置决定。例如,如果在CommandField中只有一个删除按钮,那么它的索引就是0。然而,如果在删除按钮前面还有一个编辑按钮,那么索引值是2。因为在删除按钮前面有两个控件,一个是编辑按钮,另一个是LiteralControl,用来隔离编辑按钮和删除按钮。

ButtonType obj = (ButtonType) e.Row.Cells[commandFieldIndex].Controls[controlIndex];

  在我们的例子中,CommandField使用了LinkButton,在最左端,commandFieldIndex的值是0。因为除了删除按钮,没有其他控件,所以controlIndex的值也为0。

  在引用了CommandField中的删除按钮之后,我们接下来可以获得GridView当前数据列的一些产品信息。最后,我们为删除按钮设置了OnClientClick属性的JavaScript值,其中包含了产品的名称。因为我们用单引号标记了传入confirm(string)的字符串参数,对于产品的名称我们必须要过滤可能出现在其中的单引号。具体来说,我们可以把产品名称中含有的单引号转义成,“/'“。

  做完这些改变之后,点击GridView中的删除按钮,可以显示一个定制后的确认信息(见图4)。如果用户点击弹出的确认窗口中的取消,回传将会被取消,从而阻止了删除操作发生。

  注意:我们同样可以在代码中对DetailsView的CommandField使用这种技术。然而对于DetailsView,你需要为DataBound事件提供一个处理器,因为它没有RowDataBound事件。

图4:点击GridView的删除按钮,显示一个定制的确认信息窗口

使用TemplateFields

  使用CommandField的一个缺点是必须通过索引访问到它的按钮,这会导致对象被转换成对应的按钮类型(Button,LinkButton或者ImageButton)。使用“magic numbers“和硬编码的类型会导致只有在运行时候才会被发现的错误。例如,如果你,或者其他开发人员,在将来某个时候为CommandFields添加了新的按钮(比如是编辑按钮)或者改变了ButtonType属性,现有的代码将会顺利被编译,但是当页面访问时候就可能会抛出异常或者不可预料的错误,这些直接由你书写的代码和做的改变来决定。

  一个二者择一的办法是,不使用GridView或者DetailsView的CommandFields,而是使用TemplateFields。在TemplateField中可以含有ItemTemplate,在ItemTemplate下面可以设置LinkButton或者Button,ImageButton正如CommandField中的一样。而且这些按钮的OnClientClick属性是可以显示声明的,就像FormView中看到的,或者我们可以使用以下模式在代码中适当的DataBound事件处理器中访问,
controlID是按钮ID的属性值,虽然这种办法仍然需要硬编码类型的转换,但是不再需要索引,可以改变界面而不再出现运行错误。

ButtonType obj = (ButtonType) e.Row.FindControl("controlID");

总结

  JavaScript的confirm(stirng)方法在表单递交过程中是一个经常使用的技术。当执行的时候,这个方法会显示一个模式的,客户端的窗口,包含两个按钮,一个OK(确定)一个Cancel(取消)。如果用户点击了OK(确定),confirm(string)方法会返回true,否则返回false。这种功能,以及在表单递交的事件处理器中返回false会导致浏览器取消表单提交的功能,可以用来在删除一条记录的时候的显示一个确认窗口。

  通过设置按钮控件的OnClientClick属性,可以使得这个confirm(string)方法和按钮控件的客户端onclick事件处理器相结合。当在模版中使用删除按钮的时候-或者在一个FormView的模版中,又或者一个TemplateField在DetailsView或GridView中-正如我们在教程中看到的一样,我们可以显示声明访问它或者在代码中访问它。

祝编程快乐!

作者简介

Scott Mitchell,著有六本ASP/ASP.NET方面的书,是4GuysFromRolla.com的创始人,自1998年以来一直应用 微软Web技术。Scott是个独立的技术咨询顾问,培训师,作家,最近完成了将由Sams出版社出版的新作,24小时内精通ASP.NET 2.0。他的联系电邮为mitchell@4guysfromrolla.com,也可以通过他的博客http://scottonwriting.net/与他联系。

(0)

相关推荐

  • Asp.net的GridView控件实现单元格可编辑方便用户使用

    最近做一个功能,考虑到用户使用方便,减少弹出页面,采用点"编辑"按钮无需弹出页面直接当前行的单元格内容就能编辑.进入页面显示如下图:  点"编辑"按钮后显示如下图:  编号为1的"星期"和"是否上班"均可编辑,编辑完成后,点"更新"保存. 第一张图中的数据加载是通过下述方法实现: protectedvoid GridView_RowDataBound(object sender, GridViewRowEv

  • asp.net 编辑gridview的小例子

    编辑gridview例子,完整代码如下. 复制代码 代码如下: protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)     {         GridView1.EditIndex = e.NewEditIndex;         BingGrid();     }     protected void GridView1_RowCancelingEdit(object sender, Gri

  • asp.net中gridview的查询、分页、编辑更新、删除的实例代码

    1.A,运行效果图 1.B,源代码/App_Data/sql-basic.sql 复制代码 代码如下: use mastergoif exists(select * from sysdatabases where name='db1')begin    drop database db1endgocreate database db1gouse db1go-- ================================-- ylb:1,类别表-- =====================

  • 在ASP.NET 2.0中操作数据之十七:研究插入、更新和删除的关联事件

    导言 当使用GridView.DetailsView或FormView控件的内建插入.编辑或删除特征时,在用户添加一条新记录或更新/删除一条现在记录的过程中发生了多个步骤.正如我们之前一节里所讨论的,在GridView中编辑一行时,保存(Update)和取消(Cancel)按钮将取代编辑(Edit)按钮,并且绑定列转换成TextBox.在用户更新了数据并点击保存按钮之后,下述步骤在回传时执行: 1.该GridView控件根据当前编辑行的唯一标识字段(通过DataKeyNames属性)组装它的Ob

  • ASP.NET MVC4入门教程(六):验证编辑方法和编辑视图

    在本节中,您将开始修改为电影控制器所新加的操作方法和视图.然后,您将添加一个自定义的搜索页. 在浏览器地址栏里追加/Movies, 浏览到Movies页面.并进入编辑(Edit)页面. Edit(编辑)链接是由Views\Movies\Index.cshtml视图中的Html.ActionLink方法所生成的: @Html.ActionLink("Edit", "Edit", new { id=item.ID }) Html对象是一个Helper, 以属性的形式,

  • asp.net下gridview 批量删除的实现方法第1/3页

    要实现的效果很简单,看下图片: 功能:选中CheckBox,后从数据库中删除选中项.文章侧重将如何实现批量删除,对于如何链接数据库和绑定数据不做详细解释. 1 我们先要在GridView中添加一列为CheckBox.代码如下: 复制代码 代码如下: <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">  <Columns>     

  • Asp.Net+XML操作基类(修改,删除,新增,创建)第1/2页

    /**********************************************************************************  *   * 功能说明:XML处理基类  * 作者: 刘功勋;  * 版本:V0.1(C#2.0);时间:2006-12-13  *   * *******************************************************************************/ using System;

  • 在ASP.NET 2.0中操作数据之三十六:在DataList里编辑和删除数据概述

    导言 概述插入.更新和删除数据 里我们已经学习了如何使用GridView等控件来插入,更新删除数据.通过ObjectDataSource和其它数据控件仅仅只需要在智能标签里勾一下checkbox就完成了,不需要写任何代码.而DataList没有这些内置的功能.我们可以使用1.x 里的方法来实现这些功能.在本章我们将看到,DataList提供了一些事件和属性来完成我们的目的,为此我们需要写一些代码. 本章我们首先学习如何创建一个支持编辑和删除数据的DataList.后面的教程里我们将学习一些高级的

  • asp.net GridView 删除时弹出确认对话框(包括内容提示)

    效果图: html代码 复制代码 代码如下: <table align="center" bgcolor="#c0de98" border="0" cellpadding="0" cellspacing="1" width="99%"> <tr> <th colspan="2"> GridView演示</th> <

  • 在ASP.NET 2.0中操作数据之十六:概述插入、更新和删除数据

    导言 结束前面的几节,我们已经探讨过了如何使用GridView.DetailsView和FormView控件来显示数据.这些控件简单地操作提供给它的数据.一般地,这些控件通过使用一个数据源控件,例如ObjectDataSource来存取数据.我们已经看过了ObjectDataSource是如何在ASP.NET页面和潜在的数据之间扮演一个代理的角色.当一个GridView需要显示数据时,它调用ObjectDataSource的Select()方法,这个方法转而调用一个来自我们的业务逻辑层(BLL)

  • 在ASP.NET 2.0中操作数据之十九:给编辑和新增界面增加验证控件

    导言 在前面三节的示例中,GridView和DetailsView控件使用的是绑定列和CheckBoxField(绑定GridView和DetailsView时,通过智能标记可以令VS根据数据库自动增加对应的类型).当编辑GridView或者DetailsView中的一行时,非只读属性的绑定列将自动转为textbox,以便用户修改现有的数据.同样地,当在DetailsView控件中新增记录时,InsertVisible属性为true(默认值)的绑定列会呈现出空的textbox,以接受用户输入.C

随机推荐