|
创建数据驱动窗体 所谓数据驱动窗体就是根据所请求的数据的不同生成相应的窗体。举例来讲,假设你现在有一个数据库,其中有些字段必须根据登录者的身份加以显示,授权级别高的用户可以浏览并修改这些字段的内容;授权级别一般的用户只能浏览这些字段中的数据;授权级别低的用户则不能浏览这些字段中的内容。要做到这一点就得利用VB动态添加控件的功能。 动态创建控件 无论你想要创建何种类型的数据驱动窗体,你必须知道如何在运行时动态地创建控件。你可以通过控件数组做到这一点,但VB6的Controls集合所提供的Add方法,功能更强大,灵活性更高。使用该方法,你不需要在设计时将控件的实例放在窗体上。实际上,用Add方法你甚至可以创建程序在编译时根本不存在的控件。这种方法的用法也很简单: ‘ 声明一个窗体级的变量 Sub CreateTextbox() ‘ Set txtTotal = Controls.Add(“类名”, “控件名”)
‘ 将控件移动到你所需要的地方 Controls.Remove “txtTotal” 在变量声明时加上WithEvents关键字,即使在设计时窗体不存在该控件,你也可以为该控件的事件编写代码。 上面所讲的方法只适合解决VB内置的控件。 例如,当你要添加一个TreeView控件时,VB会要求你证明你已经得到了合法的授权来创建该控件的实例。换句话说,VB要证明这个控件是买来的,而不是从其它附有该控件的程序中借来的。
要证明你经过了合法的授权有下面几种方法: 在窗体上放置一个控件。这也是最简单的方法。你完全没有必要将这个窗体显示出来。 要创建一个数据驱动窗体,仅仅知道动态创建控件还不够。例如:现在你要创建一个能根据数据库中表的不同字段自动生成控件的窗体。该窗体可能会创建单行文本框,其长度随字段长度不同而不同;也可能会创建单选按钮或复选按钮以显示布尔型字段;甚至可能创建一个多行文本框显示备注型字段。 你需要解决的第一个问题是:文本框控件的Multiline属性在运行时是只读的,只在设计时可用。幸好,微软的Microsoft Windowless Controls 6.0可以解决这个问题。这组控件集包括了轻量级的TextBox,ComboBox,ListBox,CheckBox,OptionButton,CommandButton和两个scrollbar控件。这些控件与VB内置的相应的控件最大的区别在于:这些控件的所有属性在运行时是可读写的。在VB的安装光盘中的Common\Tools\VB\WinLess文件夹中可以找到这个控件组。用下面的代码可以创建一个多行文本框: Dim WithEvents txtEditor As MSWLess.WLText Private Sub CreateEditor() 问题源自于我们无法在运行时捕获一个对象数组事件。所以我们只能采取曲线救国的办法。所要的编写的代码可能比你想象的多,不过这个解决方法很有趣,值得我们这样去做。 我们需要两个辅助类模块来捕获事件,分别取名为ControlItems和ControlItem。ControlItems是一个集合类,其中保存了ControlItem对象及其数量。该数量等于你所要对之编程的控件的数量。ControlItem类的每一份实例捕获控件产生的事件,然后调用在其所属的ControlItems集合类中的过程,最后由ControlItems在窗体中触发事件并执行事件中的代码。整个过程如下图所示: 捕获多个控件的事件 为简单起见,假设你要捕获来自所有的动态添加到窗体上去的控件的Validate事件。为完成这个工作,ControlItems集合类必须向父窗体展示该事件,并随时准备接收来自其子ControlItem类的通知以触发事件。代码如下: Event Validate(CtrlItem As ControlItem, Cancel As Boolean) ‘ 向集合中添加一个新的ControlItem项目 Friend Sub Notify_Validate(Item As ControlItem, Cancel As Boolean) 将变量声明为VBControlExtender,并加上WithEvents关键字,你就能直接捕获Validate,GotFocus,LostFocus,DragDrop和DragOver这几个事件了。如果要捕获其它更多的事件,你可以使用ObjectEvent。下面是ControlItem类模块中的代码: Public WithEvents Ctrl As VBControlExtender Sub Init(ctl As Object, parnt As ControlItems) Private Sub Ctrl_Validate(Cancel As Boolean) Dim WithEvents CtrlItems As New ControlItems Private Sub cmdCreateControls_Click() Set ctrl = Controls.Add(“MSWLess.WLText”, “One”) ctrl.Move 100, 200, 1000, 300 ctrl.Visible = True CtrlItems.Add ctrl ‘ 注意你可以使用同一个变量 Set ctrl = Controls.Add(“MSWLess.WLText”, “Two”) ctrl.Move 100, 800, 1000, 300 ctrl.Visible = True CtrlItems.Add ctrl End Sub Private Sub CtrlItems_Validate( CtrlItem As ControlItem, Cancel As Boolean) 现在解决了最困难的部分,要创建一个数据驱动窗体就变得简单了 动态添加控件 VB6有一个新功能,可以动态添加控件,不用控件数组: object.Add (ProgID, name, container) 对象名.Add (类库, 对象名, [存放对象的容器名])
参数说明 Object 必需的。一个对象表达式,其值是”应用于”列表中的一个对象。 With Form1!cmdOk .Visible = True .Width = 500 .Caption = “确认(&Y)” End With End Sub 在运行时添加未引用的控件: Option Explicit Private Sub Form_Load() 但是,为了编程这样一个未引用控件的事件,您必须使用 WithEvents 关键字声明一个对象变量为VBControlExtender 对象(如上),并且设置该对象变量到Add 方法返回的引用上。然后,利用VBControlExtender 对象的 ObjectEvent事件来编程该控件的事件。下面是一个简单的例子。 Option Explicit Private Sub LoadControl() Private Sub extObj_ObjectEvent(Info As EventInfo) Note: 不能把一个固有的控件指定给这个 VBControlExtender 变量; 任何这种试图将引起类型不匹配错误。 但是,您也可以通过使用 WithEvents 关键字声明一个对象变量,并且设置该方法返回的引用为该变量,从而编程一个动态添加控件的事件,如下所示。 Option Explicit Private Sub Form_Load() Private Sub cmdObject_Click() 注意:如果您添加一个 ActiveX 或用户控件到您的工程,但是没有在窗体中使用它,您也必须不要选定”工程属性”对话框的”生成” 选项卡上的”删除有关未使用的 ActiveX 控件”选项。如果您的应用程序试图添加该控件,那么该 Add 方法将失败,因为必需的信息已经被丢弃。 |
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/205856.html原文链接:https://javaforall.net
