True DBGrid提供了空前灵活的数据源选择,你可以直接绑定到 Visual Basic的内部数据控件、 OLE DB数据源(例如: Microsoft's ADO Data Control and Remote Data Services (RDS))、或者一个第三方数据控件(例如: APEX's True DBWizard)。在绑定模式使用 True DBGrid常常简化数据库的开发,让你能集中精神在你的应用程序界面开发上,避免了数据访问的细节。
然而,很多时候绑定到一个数据控件即不实用也不合要求。这时就需要非绑定模式下的操作。数据控件会增加开销,在大数据结果集的情况下会导致性能下降。即使是你仅需要需要在一个网格里显示一个简单的两维阵列,为什么要调入整个数据库呢?
如果你使用一个支持多行指令的数据库 API工作,应该使用基于行的非绑定模式。虽然非绑定模式是最难实现的数据访问方式,但它比应用程序模式更有效,因为需要触发的事件更少。如果新开发一个程序,应使用模式 2
TDBG支持基于行的非绑定模式,该模式不依靠 Data控件,与之相应的是,只要网格需要要接收一组相邻行或升级、添加或删除个别行,都会触发非绑定模式的事件。一个中间列缓冲对象服务作为网格和数据源之间的桥梁。
两个非绑定模式:模式 1 ―― Unbound;模式 2―― Unbound Extended,有些不同的事件语法,能简化代码,使这更加有效。
在设计的时候,设置网格的 DataMode 属性为 2- Unbound Extended,在代码里,为 UnboundReadDataEx写一个处理过程,如果你的用户需要添加、修改和删除记录,你则需要为 UnboundAddData, UnboundWriteData, 和 UnboundDeleteRow事件写处理过程
不管你是否使用模式 1 或模式 2,所有网格的 books相关属性、方法和事件 (Book, FirstRow, GetBook, FetchCellStyle, 及其他 )在基于行的非绑定模式下都和它们在 data模式下的工作方式一样,绑定和非绑定都这样

解决方案 »

  1.   

    True DBGrid 是一个数据感知ActiveX grid控件。
    Book属性:该属性为指定行返回或设置一个书签,这个行在一个RowBuffer对象里,传递到一个未绑定事件处理过程。在非绑定模式中,一个书签包含了一个用户定义的值,该值不重复地标识数据的每一行。在UnboundReadData和UnboundAddData事件里,你的代码必须为取回或添加数据的列提供书签。在UnboundWriteData和UnboundDeleteRow事件里,网格控件传递这些书签中的一个作为参数,所以你的代码能做一个适当的动作。
    True DBGrid和the Microsoft Data Access Objects (DAO) library都使用书签来标识记录和操作数据库。一个书签是一个变量,不重复地标识数据库中一个特定的行。例如:它是一个行号的概念。
    习惯于使用行号来确定记录的程序员可能需要概念性修正。在一个关系数据库中,一个记录的顺序位置是不相关的,因为在数据库或一个查询结果集中的总行数一般是无效的。当执行某个操作如FindFirst or FindNext,当前记录向前移动一个不确定的行数,并且没有有效的方法来确定移动多少。为了避免耗时的计算操作,大多数关系数据库系统都放弃了使用行号而采用书签来处理。
    书签实际上非常易于使用。下面是要记录的基本规则:
    每一个记录或行都有一个不重复的书签 
    你可以通过设置网格或Data控件的书签属性来移动到指定记录上 
    TDBGrid1.Book = SomeBookData1.Recordset.Book = SomeBookSomeBook通常是一个你从Data控件、一个副本、或一个书签集里获得的书签。网格控件或Data控件的Book属性总是包含当前记录的书签。你可以通过移动动到第一或最后记录,或移动到当前书签相关位置来游历数据库 
    Data1.Recordset.MoveFirstData1.Recordset.MoveLastData1.Recordset.MoveNextData1.Recordset.MovePrevious在绑定模式,你一般不知道书签的格式或语法,所以不要试图读一个书签的细节或自己构建一个书签。在一个书签上执行唯一的合法操作是把它存成一个变量,给它指定适当的属性或方法,并与另一个书签比较来判定两个是否一样: 
    ' Saving a book:Dim SomeBook as VariantSomeBook = Data1.Recordset.Book' Assigning a book:Data1.Recordset.Book = SomeBook' To reliably compare books, you must first convert them' into strings:Dim Bk1 As String, Bk2 As StringBk1 = SomeBook1Bk2 = SomeBook2If Bk1 = Bk2 Then...End If 注意:在VB里可靠地比较两个书签,你必须首先把他们转换到字符串
    你可以任意选择标识行的方法来作书签,但要注意的是每一行的书签必须保持不得重复。通常,你总是想能够用书签迅速地搜索记录,这样,当一个网格给你一个书签时,就要请求在你的数据集里的相关信息,你应该能够迅速定位这些网格请求的行。有一个重要的概念要记住,无论你为指定行提供给网格什么样的书签,那都是网格随后用来查寻行的依据。下面是三个使用书签的例子:1、如果你把数据和非绑定网格一起使用,你可以用一个关键字段的值来作为书签。使用这种方法,当提交书签时,你能很快地搜索和接收到相关的记录;2、如果你使用的数据库支持行号或记录号,这些可以方便地用作书签;3、如果你和一个自定义数据阵列一起使用网格,阵列的行索引是做书签的一个选择。书签不能超过255个字符,因为VB5的每个字符使用2个字节来存储,这意味着字符串书签不能超过127个字符。True DBGrid的非绑定模式支持tring, integral, and floating point书签,其他的数据类型必须转换成String才能被传进网格做书签。在从UnboundReadDataEx事件返回前,你必须用不重复的行标记填充RowBuf的Book阵列,和实际数据的Value阵列。例如:如果,offset 是1(或-1),那么你必须填进RowBuf,从StartLocation后的第几行(或先于StartLocation第几行)开始。RowBuf参数作为一个二维阵列,通过用适当的数据来设置它的Value属性,你的事件处理过程就可以从非绑定数据集传送行到grid。使用行缓冲的RowCount属性来判定grid需要多少数据行。使用它的ColumnCount属性来判定列的数量。如果ColumnCount是零,那么grid将请求一个单行的书签,如果ColumnCount不是零,那么grid将请求RowCount行数的数据和相应的书签。使用RowBuffer对象RowBuffer对象仅用在DataMode属性被设为1- Unbound 或 2 - Unbound Extended时,它仅存在于传送数据到网格或从网格传出数据时存在。你不能创建一个独立的RowBuffer对象。RowBuffer是一个可编程对象,对于在网格和你的数据源之间通过网格事件来改变数据。RowBuffer对象被作为一个参数传递进一个非绑定网格事件处理器。实际上,RowBuffer对象只能存在于非绑定事件的作用区域;你不能在代码里创建一个新的作为一个Column或Split对象。下面是RowBuffer对象属性的简要描述 RowCount属性RowCount是一个long,指出能在一个非绑定事件(read, write or add)里能被处理的最大行数,如果该属性的值超过了能被处理的行数,例如:当一个文件结尾条件被侦测到,那么你的事件处理代码应该改变这个属性,以反馈实际的行处理数量。该属性返回或设置被传递到非绑定事件处理过程中的RowBuffer对象的行数。在UnboundReadData事件中,该属性标识grid请求了多少行数据。在用Value和Book属性填充了这些行后,你的事件处理过程应该用实际取得的行数来设置RowCount属性。在UnboundAddData和UnboundWriteData事件中,该属性的值始终是1,因为一次只能添加或删除一行。但是可以把这个属性设为0来标识添加或删除操作失败。注意:当一个RowBuffer对象被传递到一个非绑定事件处理过程,RowCount属性的初始值总是反应出最大值。如果你试图超过这个最大值,将引发一个错误。RowBuffer.RowCount = LongColumnCount 属性ColumnCount是integer,指出在一个非绑定事件应该处理的列数。该属性是只读的,不要试图改变它。非绑定事件处理所有列请求。Integer = RowBuffer.ColumnCountColumnName属性ColumnName是一个string array,指定相应的网格列名到一个row buffer index。该属性是只读的。String = RowBuffer.ColumnName(ColIndex)' where ColIndex = 0 to ColumnCount – 1
     
    Book属性Book是一个variant array,当RowBuffer用来在一个非绑定读事件中取数据时,它用来指定不重复的行标记RowBuffer.Book(RowIndex) = Variant' where RowIndex = 0 to RowCount - 1 Value属性Value是一个variant array,用来指定一个由RowBuffer行和列组成的数据值RowBuffer.Value(RowIndex, ColIndex) = Variant' where RowIndex = 0 to RowCount - 1' and ColIndex = 0 to ColumnCount - 1ColumnIndex属性ColumnIndex是一个variant array,用来指定一个网格列索引,该属性是只读的。可以在UnboundReadDataEx事件里使用它,来标识哪一个数据列正在被请求。ColumnIndex属性让你判定列的索引,它用于列的标识,为了让用户用适当的列数据填入Value property array。Col = RowBuffer.ColumnIndex(RowIndex, ColIndex)' where RowIndex = 0 to RowCount - 1' and ColIndex = 0 to ColumnCount - 1非绑定模式的事件在DataMode 1 – Unbound,当网格需要判定一个相关书签时,会触发第一个事件。在需要提取数据行时会触发另一个。第一个事件是可选的,并且能被实现用来提高性能;第二个事件是强制性的UnboundGetRelativeBook:当控件需要检索一个书签时被触发UnboundReadData:当控件请求非绑定数据显示时被触发In DataMode 2 - Unbound Extended,网格触发一个单一事件去获得数据和相关书签。这个事件是强制的UnboundReadDataEx:当控件需要检索一个书签或请求非绑定数据显示时被触发 在模式1和2里,依据最终用户的权限设定,下面三个事件是可选的。UnboundWriteData:当网格控件的当前行被修改并且用户确认该修改时被触发。该事件提示你用户想要个性在非绑定数据集合里修改一行。当在代码里网格控件的Updata方面被执行时,也会触发该事件。 UnboundAddData:当用户在网格控件的新添加行里输入数据并确认时触发该事件。该事件提示你用户想要在非绑定数据集里添加新的行。UnboundDeleteRow:当用户删除当前网格控件的行时触发该事件。该事件提示你用户想从非绑定数据集里删除一行。当网格控件的Delete方法在代码里执行时,也会触发该事件。UnboundReadDataEx详细描述语法:object_UnboundReadDataEx (ByVal RowBuf As TrueDBGrid60.RowBuffer, StartLocation As Variant, ByVal Offset As Long, ApproximatePosition As Long)事件作用于TDBGrid和TDBDropDown控件参数: RowBuf是一个RowBuffer对象,用来传送数据行到网格。StartLocation是一个书签(book),和Offset一起指定数据传送的起始行。一个Null的StartLocation表示从头或从尾开始的数据。例如,如果StartLocation是Null并且Offset是2 (或-2),那么你就会从第二行(或最后两行)开始接收数据。Offset指定相于被传送数据第一行的相关位置,一个绝对数标识从相关位置的位移量。 True DBGrid 可以让用户在表格中浏览、编辑、添加和删除数据。使用建立在Visual Studio里最新的的数据绑定技术,包括OLE DB,True DBGrid 有一个完整的管理数据库接口,允许开发者在重要的特殊任务应用程序里集中,True DBGrid 还能与程序员自有数据源一起用非绑定或存储模式。 True DBGrid Pro 6.0设计成一个强大、通用并且易于使用的数据库开发工具,初级程序员可以不用写一行代码就能建立一个全功能的数据库浏览器。专业开发人员可能使用该控件的许多属性和事件来创建完善与界面友好的数据库前后端应用程序。
      

  2.   

    谢谢gunjack(gunjack)!让我一下子对TURE DBGRID有了更多的了解!
    不知在TRUE DBGRID中我能否指定每一列输入数据的范围(类型、大小),并对应不同的列显示不同的TOOLTIP?
      

  3.   

    哈哈,昨晚到1点才睡觉,终于对TDBGRID有了一个大略的了解,我的程序中的DBGRID也顺利地迁移到了TBGRID,要求达到,今天准备发分了,谢谢诸位的参与!
      

  4.   

    我也一直用True DBGrid7.0,但最近我有一個新的要求,就是怎樣使表格中的某一單元格得到焦點,和失去焦點,也就是在編程時可以控制?謝謝!