我想在ACCESS里实现一个上面这样的界面,观察了一番,决定用splitter, tab来完成。具体地说,就是用splitter把窗体分成3个窗格:上窗格、左窗格、右窗格;然后在每个窗格里放tab;然后在上窗格的tab里放listview,在左窗格的tab里放treeview,在右窗格的tab里放subform。
大体思路定了之后,就开始找控件。先找splitter。我在论坛上发帖问,有的朋友推荐component one的c1sizer,我试了,在ACCESS里不能正常工作;然后找到了FMS的splitter,它这个是专为ACCESS开发的,还可以用。就决定用它了。
然后找tab。tab控件的可选范围比较大。一种是可以直接在属性页里放控件的,比如微软的sstab,DB1的CTFOLD,还有ACCESS的标准选项卡控件,这种控件的问题在于不能和splitter很好的合作,如果属性页里放的有activex控件,那splitter移动的时候,选项卡的大小会变化,但是它里面盛的activex控件的大小却不会变化,所以选项卡最小只能变到正好把它盛的控件包住。我试过在onsplit事件里写代码改里面的控件的大小,虽然也可以勉强行,但是由于splitter事先设定选项卡最小只能改到它包容的控件那么大,所以不能很顺畅地移动splitter,只能一次移动一点点(就是从选项卡的边到它包容的控件的边那么点距离),用着不怎么爽。所以就放弃了这种tab。
再一种tab,是自己不带container的,自己要写把控件放到它的客户区域的代码,以及切换各控件显示的代码。有微软的tabstrip,还有FMS的tab,还有DB1的cttab。经过试验发现,在缩放的过程中,FMS的TABS不支持只显示部分tab,而是都挤在一堆;DB1的TABS可以显示部分tab,但是缩小到一定程度之后,出现的用来看全tab的箭头得自己编程。最后我决定用微软的tabstrip。
唉,好多次的实践都证明,最简单的是最有效的,就我现在这个简陋的编程环境(ACCESS+VBA),我还是老老实实别玩花样,否则最后往往是白费功夫。说实话,我心里渐渐地觉得,不把C#的环境搭起来不行了,太不方便了。网上适用于VBA的控件和编程经验都太少了。
用了tabstrip之后,我就在formload里,把各控件放到各tab的client区域,之后splitter就能正确地缩放各窗格的tab和控件的大小了,本来我以为还要写点代码,把splitter没正确改好的缩放改好呢,没想到这么简单。对了,子窗体的标签要去掉,因为splitter最多只能把它右边的控件的width缩到0,如果不去掉,那向右最多只能移动标签的宽度那么宽的距离。把各控件放到各tab的client区域的代码如下:
Dim tabX As MSComctlLib.tabStrip Set tabX = Me.TabStrip2.Object Me.TreeView0.Move TabStrip2.left + tabX.ClientLeft, TabStrip2.tOp + tabX.ClientTop, tabX.ClientWidth, tabX.ClientHeight Set tabX = Nothing Set tabX = Me.tabTop.Object Me.ListView1.Move tabTop.left + tabX.ClientLeft, tabTop.tOp + tabX.ClientTop, tabX.ClientWidth, tabX.ClientHeight Set tabX = Nothing Set tabX = Me.tabRight.Object Me.chdFrmAction.Move tabRight.left + tabX.ClientLeft, tabRight.tOp + tabX.ClientTop, tabX.ClientWidth, tabX.ClientHeight Set tabX = Nothing
另外,FMS的splitter缩放左右控件的规律是这样的:以垂直的splitter右边的控件为例,保持控件的right和top不动,同时保持控件的left与splitter的right之间的距离不变,缩放控件的width。
另外,在ACCESS中不支持ZORDER方法,所以切换tab时的只能把其他页面上的控件身为不可见。但是FMS splitter只对可见的控件缩放,这样在splitter移动之后再切换tab后,新可见的控件的大小就会不对。解决的方法就是在tab的click事件中,把当前页面的控件变为可见之后,在代码里改变该控件的大小(用move方法)。
另外,如果tabstrip各页面都装的是子窗体,也可以不设多个子窗体然后切换可见性,而通过设置子窗体的sourceobject,像下面这样:
Set sfInsert = Me!subInsert ' Set the subform control to show the correct sub form based on the ' tab selected Select Case Me!tabItems.Value Case 0 sfInsert.SourceObject = "frmVisibleSubProductInfo" Case 1 sfInsert.SourceObject = "frmVisibleSubSuppliers" Case 2 sfInsert.SourceObject = "frmVisibleSubCategories" End Select
补记:同样由于ACCESS对ZORDER的支持很初级。在往tabstrip上放控件的时候,一定要先放tabstrip,后放控件,否则控件就会被tabstrip挡住。