VB中动态创建控件.docx
- 文档编号:11288092
- 上传时间:2023-02-26
- 格式:DOCX
- 页数:9
- 大小:18.60KB
VB中动态创建控件.docx
《VB中动态创建控件.docx》由会员分享,可在线阅读,更多相关《VB中动态创建控件.docx(9页珍藏版)》请在冰豆网上搜索。
VB中动态创建控件
VB中动态创建控件
VB相关技术:
创建数据驱动窗体
所谓数据驱动窗体确实是依照所请求的数据的不同生成相应的窗体。
举例来讲,假设你此刻有一个数据库,其中有些字段必需依照登录者的身份加以显示,授权级别高的用户能够阅读并修改这些字段的内容;授权级别一样的用户只能阅读这些字段中的数据;授权级别低的用户那么不能阅读这些字段中的内容。
要做到这一点就得利用VB动态添加控件的功能。
动态创建控件
不管你想要创建何种类型的数据驱动窗体,你必需明白如安在运行时动态地创建控件。
你能够通过控件数组做到这一点,但VB6的Controls集合所提供的Add方式,功能更壮大,灵活性更高。
利用该方式,你不需要在设计时将控件的实例放在窗体上。
事实上,用Add方式你乃至能够创建程序在编译时全然不存在的控件。
这种方式的用法也很简单:
'声明一个窗体级的变量
DimWithEventstxtTotalAsTextBox
SubCreateTextbox()
'创建新的Textbox控件
SettxtTotal=("","txtTotal")
'将控件移动到你所需要的地方
1000,800,1200,300
'创建时,所有的控件都是不可见的
=True
EndSub
请注意Add方法的第二个参数:
分配给控件的名称。
从代码可读性出发,这个名称一般都与变量名相同。
你可以用这个名称从Controls集合中获取相应的控件或移除该控件。
例如:
"txtTotal"
在变量声明时加上WithEvents关键字,即便在设计时窗体不存在该控件,你也能够为该控件的事件编写代码。
上面所讲的方式只适合解决VB内置的控件。
例如,当你要添加一个TreeView控件时,VB会要求你证明你已经取得了合法的授权来创建该控件的实例。
换句话说,VB要证明那个控件是买来的,而不是从其它附有该控件的程序中借来的。
要证明你通过了合法的授权有下面几种方式:
在窗体上放置一个控件。
这也是最简单的方式。
你完全没有必要将那个窗体显示出来。
将相关的控件添加到工具箱中,然后在“工程属性”对话框的“生成”标签页中取消选择“删除有关未使用的ActiveX控件的信息”这一项。
向Licenses集合添加一个元素。
例如:
("")
仅仅创建了控件并不足够
要创建一个数据驱动窗体,仅仅明白动态创建控件还不够。
例如:
此刻你要创建一个能依照数据库中表的不同字段自动生成控件的窗体。
该窗体可能会创建单行文本框,其长度随字段长度不同而不同;也可能会创建单项选择按钮或复选按钮以显示布尔型字段;乃至可能创建一个多行文本框显示备注型字段。
你需要解决的第一个问题是:
文本框控件的Multiline属性在运行时是只读的,只在设计时可用。
幸亏,微软的MicrosoftWindowlessControls能够解决那个问题。
这组控件集包括了轻量级的TextBox,ComboBox,ListBox,CheckBox,OptionButton,CommandButton和两个scrollbar控件。
这些控件与VB内置的相应的控件最大的区别在于:
这些控件的所有属性在运行时是可读写的。
在VB的安装光盘中的Common\Tools\VB\WinLess文件夹中能够找到那个控件组。
用下面的代码能够创建一个多行文本框:
DimWithEventstxtEditorAs
PrivateSubCreateEditor()
SettxtEditor=("","txtEditor")
0,0,4000,4000
=True
=wlBoth
=True
EndSub
另外一个问题比较复杂:
在事先不知道要创建多少个控件的情况下,如何给每个对新创建的控件的引用分配唯一的带WithEvents关键字的变量。
换句话说就是要对新创建的控件的事件进行编程,前提是你在设计时不知道程序会创建多少个控件。
使用对象数组显然不行,因为不能用WithEvents关键字声明一个对象数组;更坏的情况是,资一个变量定义为AsControl或AsObject也不行,因为还是不能用WithEvents。
问题源自于咱们无法在运行时捕捉一个对象数组事件。
因此咱们只能采取曲线救国的方法。
所要的编写的代码可能比你想象的多,只是那个解决方式很有趣,值得咱们如此去做。
咱们需要两个辅助类模块来捕捉事件,别离取名为ControlItems和ControlItem。
ControlItems是一个集合类,其中保留了ControlItem对象及其数量。
该数量等于你所要对之编程的控件的数量。
ControlItem类的每一份实例捕捉控件产生的事件,然后挪用在其所属的ControlItems集合类中的进程,最后由ControlItems在窗体中触发事件并执行事件中的代码。
整个进程如以下图所示:
捕捉多个控件的事件
为简单起见,假设你要捕捉来自所有的动态添加到窗体上去的控件的Validate事件。
为完成那个工作,ControlItems集合类必需向父窗体展现该事件,并随时预备接收来自其子ControlItem类的通知以触发事件。
代码如下:
EventValidate(CtrlItemAsControlItem,CancelAsBoolean)
Privatem_ControlItemsAsNewCollection
'向集合中添加一个新的ControlItem项目
FunctionAdd(ctrlAsControl)AsControlItem
DimnewItemAsNewControlItem
ctrl,Me
'添加到私有类
newItem
'返回新项目给调用者
SetAdd=newItem
EndFunction
FriendSubNotify_Validate(ItemAsControlItem,CancelAsBoolean)
RaiseEventValidate(Item,Cancel)
EndSub
ControlItem类必须捕获来自动态添加到窗体中的控件的事件,并通知其所属的ControlItems集合类。
很显然,ControlItem类必须有一个用WithEvents关键字定义的变量来引用真正的控件。
这意味着你不能将变量声明为AsControl或AsObject。
如果你决定在窗体中所动态添加的控件不使用VB内置的控件的话,这个问题的解决办法相当的简单。
你只需要将变量声明为VBControlExtender类型就行了。
对于创建数据驱动窗体来讲,不使用VB内置的控件并不是一件大不了的事。
将变量声明为VBControlExtender,并加上WithEvents关键字,你就能够直接捕捉Validate,GotFocus,LostFocus,DragDrop和DragOver这几个事件了。
若是要捕捉其它更多的事件,你能够利用ObjectEvent。
下面是ControlItem类模块中的代码:
PublicWithEventsCtrlAsVBControlExtender
'所属的ControlItems对象
Dimm_ParentAsControlItems
SubInit(ctlAsObject,parntAsControlItems)
SetCtrl=ctl
Setm_Parent=parnt
EndSub
PrivateSubCtrl_Validate(CancelAsBoolean)
'通知所属的ControlItems类
Me,Cancel
EndSub
将下面的代码放入窗体中,就可以捕获动态添加的控件所产生的事件了:
DimWithEventsCtrlItemsAsNewControlItems
PrivateSubcmdCreateControls_Click()
DimctrlAsControl
'创建两个文本框并将它们添加到ControlItems集合?
Setctrl=("","One")
100,200,1000,300
=True
ctrl
'注意你可以使用同一个变量
Setctrl=("","Two")
100,800,1000,300
=True
ctrl
EndSub
PrivateSubCtrlItems_Validate(CtrlItemAsControlItem,CancelAsBoolean)
'拒绝空字符串-注意如何引用控件的属?
If=""
ThenCancel=True
EndSub
此刻解决了最困难的部份,要创建一个数据驱动窗体就变得简单了
**************************************************************
****************************************************************
动态添加控件
VB6有一个新功能,能够动态添加控件,不用控件数组:
(ProgID,name,container)
参数说明
Object必需的。
一个对象表达式,其值是“应用于”列表中的一个对象。
ProgID必需的。
一个标识控件的字符串。
大多数控件的ProgID都可通过查看对象浏览器来决定。
控件的ProgID是由控件的库和类组成的。
例如,CommandButton控件的ProgID是。
在ProgID与对象浏览器中所显示的不一样的情况下,VisualBasic
将显示一个包括正确ProgId的错误信息。
name必要的。
一个字符串,用来标识集合的成员。
container可选的。
一个对象引用,它指定控件的容器。
如果没有指定或为NULL,缺省值为Controls集合所属的容器。
通过指定该参数,可以把一个控件放置在任何现存的容器控件(如Frame控件)中。
用户控件或ActiveX文档也可以作为一个容器。
举例:
isible=True
.Width=500
.Caption="确认(&Y)"
EndWith
EndSub
重点:
当您添加一个未引用的需要许可证的控件到一个现存的(已部署好的)应用程序时,在利用Add方式之前您必需也添加那个控件的许可证关键字。
在运行时添加未引用的控件:
您也可以利用Add方法来动态添加一个在工程中没有被引用的控件。
(“未引用的”控件是不出现在Toolbox中的控件)。
为此,您必须也把控件的License关键字添加到Licenses集合中。
下面的示例中在添加控件本身之前添加了控件的许可证关键字:
OptionExplicit
PrivateWithEventsextCtlAsVBControlExtender
PrivateSubForm_Load()
"","xydsfasfjewfe"
SetextCtl="","ctl1")
=True'Thecontrolisinvisiblebydefault.
EndSub
可是,为了编程如此一个未引用控件的事件,您必需利用WithEvents关键字声明一个对象变量为VBControlExtender对象(如上),而且设置该对象变量到Add方式返回的引用上。
然后,利用VBControlExtender对象的ObjectEvent事件来编程该控件的事件。
下面是一个简单的例子。
OptionExplicit
DimWithEventsobjExtAsVBControlExtender'声明Extender变量
PrivateSubLoadControl()
"","xydsfasfjewfe"
SetobjExt=("","myCtl")
=True
EndSub
PrivateSubextObj_ObjectEvent(InfoAsEventInfo)
'使用SelectCase编程控件的事件。
SelectCase
Case"Click"
'这里处理Click事件。
'现在显示其他的case
CaseElse'未知事件
'这里处理未知事件。
EndSelect
EndSub
Note:
不能把一个固有的控件指定给那个VBControlExtender变量;任何这种试图将引发类型不匹配错误。
可是,您也能够通过利用WithEvents关键字声明一个对象变量,而且设置该方式返回的引用为该变量,从而编程一个动态添加控件的事件,如下所示。
OptionExplicit
'声明对象变量为CommandButton。
PrivateWithEventscmdObjectAsCommandButton
PrivateSubForm_Load()
SetcmdObject="","cmdOne")
=True
="DynamicCommandButton"
EndSub
PrivateSubcmdObject_Click()
Print"Thisisadynamicallyaddedcontrol"
EndSub
如果希望添加一个用户控件或任何ActiveX控件到您的窗体,必须或者把这个控件添加到“工具箱”,或者把控件的License关键字添加到Licenses集合中。
有关详细信息请参阅“增加方法(Licenses集合)”。
注意:
若是您添加一个ActiveX或用户控件到您的工程,可是没有在窗体中利用它,您也必需不要选定“工程属性”对话框的“生成”选项卡上的“删除有关未利用的ActiveX控件”选项。
若是您的应用程序试图添加该控件,那么该Add方式将失败,因为必需的信息已经被抛弃。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VB 动态 创建 控件