深入CursorAdapter(四)
来源:优易学  2011-12-9 18:16:03   【优易学:中国教育考试门户网】   资料下载   IT书店

 

  要测试一下的话,请运行 TestCustomersCursor.prg,它会从 SQL Server 版本的 Northwind 数据库中 Customers 表的一个客户,然后做到 Access 版本的 Northwind 数据库所做的同样的事情。这个示例演示了怎样不为类指定连接信息,这个类自己就能灵活的完成任务,因此,它的可重用性是很强的。

  示例:表单

  现在我们已经有了一些可重用类,让我们来用用它们。首先,我们来建立 SFDataEnvironment 的一个子类 CustomersAndOrdersDataEnvironment (哈哈,名字可有够长的,D.H牌冰糖葫芦!),它包含着一个 CustomerByIDCursor 类和一个 OrdersForCustomerCursor 类。由于我们希望在打开表之前设置连接信息,因此把它的 AutoOpenTables 属性设置为了 .F.,而且把前面两个 CursorAdapter 的 UseDEDataSource 属性都设置为了 .T.。现在,这个数据环境类已经可以被用来在某个表单中显示关于一个指定客户的信息以及他的订单了。

  让我们来建立这么一个表单。附件中的 CustomerOrders.scx 表单的 DEClass 和 DEClassLibrary 属性已经被设置为了CustomersAndOrdersDataEnvironment 和 NorthwindDataClasses.vcx,这样就用上了我们的可重用数据环境类。这个表单的 Load 方法里面的代码有点多,不过这是因为它要支持 ADO、ODBC、以及 XML 数据源,并且它还要建立自己的连接,所以大多数代码都是处理这些问题的。如果它只支持一种数据源的话,比如只用 ODBC,再比如由另一个对象来管理连接(实际的应用程序开发中常常就是这样的),代码就会简单多了:

  with This.CustomersAndOrdersDataEnvironment
  * 获得连接
  lnHandle = oApp.oConnectionMgr.GetConnectionHandle()
  .SetConnection(lnHandle)

  * 指定从 CustomerID 文本框中取得 cursor 参数的值
  loParameter = ;
  .CustomerByIDCursor.GetParameter('pCustomerID')
  loParameter.value = '=Thisform.txtCustomerID.value'
  loParameter = ;
  .OrdersForCustomerCursor.GetParameter('pCustomerID')
  loParameter.value = '=Thisform.txtCustomerID.value'

  * 建立一个空的 cursor,如果失败的话则显示错误信息

  if not .GetData(.T.)
  messagebox(.cErrorMessage)
  return .F.
  endif not .GetData(.T.)
  endwith

  这段代码用上了那两个 CursorAdapter 对象的 GetParameter 方法来把 pCustomerID 参数设置为表单上一个文本框中的值。注意在值里面用到的'=',它表示在你需要 value 属性的时候再去运算它的值,所以我们实际上有了一个动态的参数(这样就顺应了当用户在文本框中输入了新的值以后要将改动反应到参数中去的需要)。调用 GetData 方法是为了建立一个空的 Cursor,这样才能安顿那些数据绑定的控件。

  txtCustomerID 文本框没有绑定什么数据。它的 Valid 方法先调用数据环境的 Requery 方法,然后再调用表单的 Refresh 方法。这样,当用户输入一个新的客户ID的时候,就能够 Requery 那个 Cursor,接着表单上其它控件也会被刷新。表单上的其它文本框被绑定到由 CustomersByIDCursor 对象建立的 Customers cursor 的字段中。那个 Grid 被绑定到由 OrdersForCustomerCursor 对象建立的 Orders Cursor。

  运行这个表单,并输入一个 Customer ID 为“ALFKI”(见图1)。当你按下 Tab 键跳出这个文本框的时候,你会看到该客户的地址信息以及他的订单就出现了。试着改动一些这个客户的数据或者订单数据,然后关闭表单再打开,再输入一次“ALFKI”,你会看到你没做什么工作这些改动就都已经被写到后台数据库中了。

  酷吧,嗯?跟建立一个基于本地表或者视图的表单相比,并没多多少工作。更棒的是:试试把定义在 Load 方法中的 ccDATASOURCETYPE 常量改变为 “ADO”或者“XML”,然后这个表单无论是看起来还是实际工作起来都跟没改过之前一摸一样(如果你想用 XML,你需要象上个月的文章中所说的那样为 Northwind 数据库设置一个 SQLXML 虚拟目录,并把本月附件中的 XML 模板文件拷贝到那个目录里)。

  示例:报表

  我们来试试报表。这里最大的问题是:与表单不同,我们既不能告诉报表去使用一个数据环境子类,也不能拖放一个 CursorAdapter 子类到数据环境中去。所以我们不得不向报表放入一些代码以将 CursorAdapter 添加到数据环境。尽管从逻辑上来看应该把这些代码放到报表数据环境的 BeforeOpernTables 事件中去,不过事实上这样做却是行不通的,因为——由于某些我不能理解的原因—— BeforeOpenTables 事件只会在你预览报表的每一页的时候才会触发。所以,我们只好把代码放在 Init 方法里。因为演示的需要,报表 CustomerOrders.frx 跟表单 CustomerOrders.scx 一样,要比实际开发的情况下会用到的代码更复杂一些。如果没有这些演示的需求的话,实际上可以简化到下面这样:
  with This
  set safety off

  * 获得连接
  .DataSource = oApp.oConnectionMgr.GetConnectionHandle()

  * 建立客户和订单的 CursorAdapter 对象
  .NewObject('CustomersCursor', 'CustomersCursor', ;
  'NorthwindDataClasses')
  .CustomersCursor.AddTag('CustomerID', 'CustomerID')
  .CustomersCursor.UseDEDataSource = .T.
  .NewObject('OrdersCursor', 'OrdersCursor', ;
  'NorthwindDataClasses')
  .OrdersCursor.AddTag('CustomerID', 'CustomerID')
  .OrdersCursor.UseDEDataSource = .T.

  * 取得数据,如果失败,则显示错误信息
  if not .CustomersCursor.GetData()
  messagebox(.CustomersCursor.cErrorMessage)
  return .F.
  endif not .CustomersCursor.GetData()

  if not .OrdersCursor.GetData()
  messagebox(.OrdersCursor.cErrorMessage)
  return .F.
  endif not .OrdersCursor.GetData()

  * 从 Customers 设置一个与 Orders 的关系
  set relation to CustomerID into Customers
  endwith
  这里的代码比表单示例的要多一些,这是因为我们不能使用自定义的数据环境类导致不得不自己手动编码来代替。
  现在,我们怎样才能尽可能简单的就把那些字段放到报表上去呢?由于 CursorAdapter 对象是我们用代码在运行时才添加到数据环境中去的,在设计时就没办法享受到拖放字段到报表上的方便了。这里有个小技巧:建立一个会建立这些 Cursor 的 PRG文件,并让这些 Cursor 处于有效范围内(可以采用挂起 PRG 的运行或者把 CursorAdapter 对象声明成 Public 的办法),然后使用快速报表功能来把那些字段放到报表上,这样报表控件的大小也设置好了。
  当你预览报表的时候该报表的情况。如果结合表单一起使用的话,你可以试试改动表单数据环境中的 #DEFINE 语句来换用其它类型的数据源。

  总结

  我们对新的 CursorAdapter 基础类的研究就到这里了。我个人对 CursorAdapter 的出现感到非常的兴奋,并计划给我的应用程序框架中的数据处理部件升升级以更充分的利用它的优点。

  下个月,我们将研究一下在 VFP 8 中通过 Try ... Catch ... Finally ... EndTry 命令大大增强了的错误处理方式以及新的 Exception 基础类。

上一页  [1] [2] 

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训