中琅软件教程网

首页搜索登录
首页业界网页平面多媒体程序数据库办公工具服务器系统网络安全站长认证壁纸
加入收藏 | 网站地图 | | RSS | WAP
你好,游客 登录 注册 搜索

演练:使用 DataGrid Web 控件读取和写入数据(3)

[日期:2006-09-28] 作者: 来源: [字体: ]
     测试到目前为止具有的功能
  现在您具有一个 DataGrid 控件,该控件显示数据集(在从数据库填充了数据集之后)中的数据,并且还对网格进行了配置,每行都有一个“编辑”按钮。虽然页尚未完成,但现在对其进行测试以确保编辑功能可以正常工作是十分有用的。
  
  测试目前具有的功能
  
  在解决方案资源管理器中,右击 Web 窗体页并选择“在浏览器中查看”。
  当前项目将被编译,Web 窗体页将显示在设计器的浏览器窗格中。如果一切工作正常,则网格将填充有数据,网格的第一列将包含标有“编辑”的链接。
  
  单击网格中任何行的“编辑”链接。
  将重新显示该行,并带有以下更改:
  
  “编辑”替换为“更新”和“取消”链接。
  数据重新显示在 TextBox 控件中。
  单击“取消”。
  该行重新显示在其原始窗体中。
  
  下一节详细介绍如何让“更新”链接将更改从网格写入数据集和数据库。
  
  更新数据集和数据库
  至此,DataGrid 控件已完成了仅显示数据所涉及的大部分工作。但是,与其他 ASP.NET 服务器控件一样,该网格不包括自动更新条款(即接受用户在网格中进行的更改,并将更改发送回数据源)。若要执行更新,您需要编写一些代码。
  
  更新实际以两个阶段发生。首先,您必须用在网格中进行的更改更新数据集。然后,您必须将数据集中的更改写回数据库。有关更多信息,请参见数据集更新介绍。
  
  当网格行处于编辑模式时,最左边的一列包含“更新”链接。当用户单击该链接时,它引发一个 UpdateCommand 事件。您将在该事件的处理程序中编写所有更新代码。
  
  创建 UpdateCommand 处理程序
  
  (在 Visual Basic 中)如果尚未将其打开,则再次打开代码编辑器。
  - 或 -
  
  (在 Visual C# 中)在“设计”视图中,选择网格并按 F4 键打开“属性”窗口。
  
  (在 Visual Basic 中)在代码编辑器上方的左侧下拉列表中选择“DataGrid1”。
  - 或 -
  
  (在 Visual C# 中)单击“属性”窗口顶部的“事件”按钮 ()。
  
  (在 Visual Basic 中)在代码编辑器顶部右侧的下拉列表中选择“UpdateCommand”。
  - 或 -
  
  (在 Visual C# 中)双击网格中的“UpdateCommand”。
  
  创建了一个 DataGrid1_UpdateCommand 事件处理程序。
  
  从 DataGrid 控件进行更新的步骤
  您将执行的操作的大纲如下:
  
  确定 DataGrid 控件中哪一行(根据索引)已被更新。然后,从该网格行获取数据键,以便确定正在更新的行(根据 ID)。
  从用户更新的网格行获取更改的值。
  使用数据键值在数据集表中查找对应的行,然后将更改写入该行。此时,您已更新了数据集,但未更新数据库本身。
  将更改从数据集发送到数据库。这执行将更改从数据集复制到数据库的 SQL 命令或存储过程。
  刷新 DataGrid 控件的内容。
  下面一节解释这些步骤中每一步的详细情况。如果愿意,您可以跳过这些解释,直接进入随后的代码。
  从 DataGrid 控件进行更新
  
  通过获取传入事件对象的行(Item 对象)的 ItemIndex 属性确定哪个 DataGrid 行已被更新。然后使用该索引值从网格的 DataKeys 集合中获取对应的值。
  ' Visual Basic
   Dim key As String = DataGrid1.DataKeys(e.Item.ItemIndex).ToString()
   // C#
   string key = DataGrid1.DataKeys[e.Item.ItemIndex].ToString();
  从 DataGrid 行中获取更改的值。若要完成该操作,请:
  从传入事件对象的项的 Cells 集合中获取适当的单元格(从零开始的)。例如,网格中最左边一列为 Cells(0)。
  对于每个单元格,获取其 Controls 集合,它包含显示在该单元格中的所有元素。
  从该集合中获取且仅获取第一个控件,在本例中为 TextBox 控件。若要获取 TextBox,声明一个类型 TextBox 的局部变量,并将 Controls 集合中的对象分配给它。
  获取 TextBox 控件的值(其 Text 属性)。
  下面的示例显示如何执行这些步骤。
  
  ' Visual Basic
   Dim categoryName, categoryDescription As String
   Dim tb As TextBox
   tb = CType(e.Item.Cells(2).Controls(0), TextBox)
   categoryName = tb.Text
   tb = CType(e.Item.Cells(3).Controls(0), TextBox)
   categoryDescription = tb.Text
   // C#
   string categoryName;
   string categoryDescription;
   TextBox tb;
   tb = (TextBox) e.Item.Cells[2].Controls[0];
   categoryName = tb.Text;
   tb = (TextBox) e.Item.Cells[3].Controls[0];
   categoryDescription = tb.Text
  在数据表中查找对应的行。类型化的 dsCategories 数据集包含一个特殊的 FindBy 方法(在本例中为 FindByCategoryID 方法),该方法通过行的主键定位行,并返回一个对行的引用。创建类型化数据行的变量并调用该方法:
  ' Visual Basic
   Dim r As dsCategories.CategoriesRow
   r = DsCategories1.Categories.FindByCategoryID(key)
   // C#
   dsCategories.CategoriesRow r;
   r = dsCategories1.Categories.FindByCategoryID(int.Parse(key));
  通过更改您在第三步所在行中的值更新该行,如下面的示例所示:
  ' Visual Basic
   r.CategoryName = categoryName
   r.Description = categoryDescription
   // C#
   r.CategoryName = categoryName;
   r.Description = categoryDescription;
  通过调用数据适配器的 Update 方法将更改从数据集发送到数据库:
  ' Visual Basic
   SqlDataAdapter1.Update(DsCategories1)
   DataGrid1.DataBind()
   // C#
   sqlDataAdapter1.Update(dsCategories1);
   DataGrid1.DataBind();
  将网格中的当前行切换出编辑模式。
  ' Visual Basic
   DataGrid1.EditItemIndex = -1
   // C#
   DataGrid1.EditItemIndex = -1;
  数据绑定 DataGrid 控件:
  ' Visual Basic
   DataGrid1.DataBind()
   // C#
   DataGrid1.DataBind();
  下面的代码显示完成的 UpdateCommand 事件处理程序是什么样的。复制该代码并将其粘贴到 Web 窗体页的类文件。
  
  提示 一定要改写先前创建的主干事件处理程序,否则将有两个方法具有相同的名称和签名。
  ' Visual Basic
  Private Sub DataGrid1_UpdateCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles DataGrid1.UpdateCommand
  Dim categoryName, categoryDescription As String
  ' Gets the value of the key field of the row being updated
  Dim key As String = DataGrid1.DataKeys(e.Item.ItemIndex).ToString()
  ' Gets get the value of the controls (textboxes) that the user
  ' updated. The DataGrid columns are exposed as the Cells collection.
  ' Each cell has a collection of controls. In this case, there is only one
  ' control in each cell -- a TextBox control. To get its value,
  ' you copy the TextBox to a local instance (which requires casting)
  ' and extract its Text property.
  '
  ' The first column -- Cells(0) -- contains the Update and Cancel buttons.
  Dim tb As TextBox
  ' Gets the value the TextBox control in the third column
  tb = CType(e.Item.Cells(2).Controls(0), TextBox)
  categoryName = tb.Text
  ' Gets the value the TextBox control in the fourth column
  tb = CType(e.Item.Cells(3).Controls(0), TextBox)
  categoryDescription = tb.Text
  ' Finds the row in the dataset table that matches the
  ' one the user updated in the grid. This example uses a
  ' special Find method defined for the typed dataset, which
  ' returns a reference to the row.
  Dim r As dsCategories.CategoriesRow
  r = DsCategories1.Categories.FindByCategoryID(key)
  ' Updates the dataset table.
  r.CategoryName = categoryName
  r.Description = categoryDescription
  ' Calls a SQL statement to update the database from the dataset
  SqlDataAdapter1.Update(DsCategories1)
  ' Takes the DataGrid row out of editing mode
  DataGrid1.EditItemIndex = -1
  ' Refreshes the grid
  DataGrid1.DataBind()
  End Sub
  // C#
  private void DataGrid1_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
  {
  string categoryName, categoryDescription;
  // Gets the value of the key field of the row being updated
  string key = DataGrid1.DataKeys[e.Item.ItemIndex].ToString();
  // Gets get the value of the controls (textboxes) that the user
  // updated. The DataGrid columns are exposed as the Cells collection.
  // Each cell has a collection of controls. In this case, there is only one
  // control in each cell -- a TextBox control. To get its value,
  // you copy the TextBox to a local instance (which requires casting)
  // and extract its Text property.
  //
  // The first column -- Cells(0) -- contains the Update and Cancel buttons.
  TextBox tb;
  // Gets the value the TextBox control in the third column
  tb = (TextBox)(e.Item.Cells[2].Controls[0]);
  categoryName = tb.Text;
  // Gets the value the TextBox control in the fourth column
  tb = (TextBox)(e.Item.Cells[3].Controls[0]);
  categoryDescription = tb.Text;
  // Finds the row in the dataset table that matches the
  // one the user updated in the grid. This example uses a
  // special Find method defined for the typed dataset, which
  // returns a reference to the row.
  dsCategories.CategoriesRow r;
  r = dsCategories1.Categories.FindByCategoryID(int.Parse(key));
  // Updates the dataset table.
  r.CategoryName = categoryName;
  r.Description = categoryDescription;
  // Calls a SQL statement to update the database from the dataset
  sqlDataAdapter1.Update(dsCategories1);
  // Takes the DataGrid row out of editing mode
  DataGrid1.EditItemIndex = -1;
  // Refreshes the grid
  DataGrid1.DataBind();
  }
  测试
  现在您已完成所有操作。若要阐释网格如何工作并确保它正确更新数据,您应该对页进行测试。
  
  对页进行测试
  
  在解决方案资源管理器中,右击 Web 窗体页并选择“在浏览器中查看”。
  当前项目将被编译,Web 窗体页将显示在设计器的浏览器窗格中。
  
  单击网格中任何一行的“编辑”链接,然后使用文本框编辑该行。
  单击“更新”。
  网格重新显示,并带有您的更改。如果检查数据库,您将看到已适当写入更改。
  
  后续步骤
  在本演练中,您使用 Web 窗体页上的 DataGrid 控件的目的不仅仅是查看数据,而且要编辑数据。为了清楚起见,本演练跳过了一些在成品应用程序中要考虑的细节。您要对本演练中所学的内容有所加强的一些方面包括:
  
  增强 DataGrid 控件的功能
  本演练没有利用 DataGrid 控件的某些更高级的功能。您可以增强的方面包括:
  
  通过选择特定的要显示的列、更改列标题等配置网格中的个别列。有关详细信息,请参见向 DataGrid Web 服务器控件添加绑定列和指定 DataGrid Web 服务器控件中网格项的格式
  允许用户删除行。有关详细信息,请参见允许用户删除 DataGrid Web 服务器控件中的项。除了指定“删除”按钮之外,您需要添加代码以从数据集中移除记录。有关详细信息,请参见删除数据集中的记录。
  使用分页。在本例中,您只显示几条记录。但是,经常要显示更多的记录,如果是这样,允许网格以一次一页的方式显示信息是非常必要的。有关详细信息,请参见 DataGrid Web 服务器控件中的分页行为。
  缓存数据集
  在本演练中,页每次到服务器的往返过程都会使数据集重新实例化并从数据库重新填充数据集。这种策略虽然实现起来非常简单,但是却会导致到数据库服务器不必要的通信量。
  
  一种替代方法是在填充数据集和每次更改数据集之后将数据集存储起来。于是您可以在每次往返过程发生后恢复数据集,而不用重新读取数据库信息。存储数据集有多种方法,其中包括存储在会话状态(在服务器上)或视图状态(在客户端上,页中)。有关要使用哪种策略的详细信息,请参见状态管理建议。
  
  例如,如果您要在会话状态中存储数据集,则可能要在 Page_Load 事件处理程序中包括以下代码:
  
  ' Visual Basic
  If Session("mydatset") Is Nothing Then
  SqlDataAdapter1.Fill(DsCategories1)
  Session("mydataset") = DsCategories1
  Else
  DsCategories1 = CType(Session("mydatset"), dsCategories)
  End If
  If Not Page.IsPostBack Then
  DataGrid1.DataBind()
  End If
  // C#
  if (Session["mydatset"] == null)
  {
  sqlDataAdapter1.Fill(dsCategories1);
  Session["mydataset"] = dsCategories1;
  }
  else
  {
  dsCategories1 = (dsCategories)Session["mydatset"];
  }
  if (! Page.IsPostBack)
  {
  DataGrid1.DataBind();
  }
  请注意,如果要在会话状态或应用程序状态中存储数据集,则当将其取回时需要将其强制转换为适当的数据集类型。
  
  每次数据集更改时,一定要刷新会话状态中该数据集的副本。例如,您可能要在 UpdateCommand 事件处理程序中紧接在更新数据库之后添加下面一行:
  
  ' Visual Basic
  SqlDataAdapter1.Update(DsCategories1)
  Session("mydataset") = DsCategories1
  // C#
  sqlDataAdapter1.Update(dsCategories1);
  Session["mydataset"] = dsCategories1;
  使用对数据库的直接访问代替数据集
  在演练中,您创建了一个数据集并将网格绑定到该数据集。若要更新数据库,首先更新数据集,然后使用数据适配器的 Update 方法将更改发送到数据库。
  
  使用数据集便于执行更新,但其代价是一些内存和微小的性能系统开销。作为一种替代方法,您可以使用数据命令(OleDbCommand 类或 SqlCommand 类对象)直接执行 SQL 语句或存储过程。例如,您可以配置一个带有参数化 SQL Update 语句的数据命令来更新数据库中的 Categories 表。在获取网格中的更改之后,设置 Update 语句的参数然后执行它。
  
  有关更多信息,请参见 Visual Studio 中的 DataCommand 对象介绍。
  
  验证数据
  在成品应用程序中,您可能要包括验证检查以确保用户输入的更改是有效的。有关详细信息,请参见数据集中的数据验证。
  
  并发控制
  在本演练中,您将更新发送到数据库而没有考虑您正在更新的记录是否已被另一个用户更改。但是,在成品应用程序中,通常要包括错误检查以确保维护了数据库的完整性。有关详细信息,请参见 ADO.NET 中的并发控制。
  
  使用 DataGrid 控件添加记录
  虽然 DataGrid 控件允许您显示和编辑数据,但它无法直接给数据集或数据库表添加新记录。通过使用如下所示的策略,您可以间接添加此功能:
  
  向数据源中添加一条新的空白记录。
  重新绑定网格;这将显示新的空白记录。
  使新网格行处于编辑模式,并在用户保存更改时,以用户的信息更新新记录,就像更改任何现有记录一样。
  您采取的具体步骤取决于您正在使用的数据源的类型(例如,该数据源是数据集还是数据库本身)。您也可能会遇到主键或外键约束对新记录施加的限制。
  
  使用 DataGrid 控件添加新记录的示例在有关 DataGrid Web 服务器控件的常见问题中说明。
  
  安全
  在创建 Web 窗体时,您应该了解可能发生的安全性问题的类型。有关详细信息,请参见 Web 应用程序安全威胁概述。
    做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。

关键词:

收藏 推荐 打印 | 录入:blue1000 | 阅读:
本文评论   查看全部评论 (0)
表情: 姓名: 字数
点评:
       
评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事/刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款