允许开发者在您的控件上放置控件

某些控件可以作为其它控件的容器。例如,如果在 Visual Basic 的 PictureBox 控件上放置控件,那么当 PictureBox 移动时,所有的控件都跟着移动。Visual Basic 用户可以利用这种功能对控件分组,或者生成可滚动的图片,等等。

将 UserControl 对象的 ControlContainer 属性置为 True,即可允许开发者在 ActiveX 控件上放置控件。

注意   轻量用户控件不能作为控件容器使用。如果一个 UserControl 对象的 Windowless 属性被设置为 True,那么其 ControlContainer 属性将被忽略。关于轻量用户控件的细节,请参阅本章后面的“创建轻量控件”。

开发者在 ActiveX 控件实例上放置的控件可以通过 UserControl 对象的 ContainerControl 集合访问。在设计时或运行时都可以使用该集合。

ContainedControls 集合与控件组合

与 Controls 集合不同,ContainedControls 集合只包含设计 ActiveX 控件时用到的子控件。图 9.7 说明了这一点,其中假定 ShapeLabel 控件的 ControlContainer 属性为 True。

图 9.7 Controls 和 ContainedControls 集合

ContainedControls 集合的可用性

在 UserControl 对象的 Initialize 事件中不能访问 ContainedControls 集合。对 ControlContainer 特性的支持由用来放置控件的对象提供,所以控件必须在 ContainerControls 成为可用的之前放置在容器对象上。当 UserControl 对象收到 ReadProperties 事件时,定位已经完成。

当控件被定位,并且已经提供了对 ControlContainer 特性的支持之后,ContainedControls 集合也许不会立即包含对放置在您的控件上的控件的引用。例如,如果控件在 Visual Basic 窗体上,则 ContainedControls 集合的 Count 属性将一直为零,直到执行了 UserControl_ReadProperties 事件过程为止。

ControlContainer 对性能的影响

如果允许开发者在 ActiveX 控件实例上放置其它控件,就将导致额外的开销。必须对被包含的控件进行裁剪,而且被包含的控件必须出现在 UserControl 中所有的子控件之上,并且显然需要对 ContainedControl 集合进行维护。

换句话说,作为其它控件的容器的控件是严重影响性能的控件。

为了提高控件的性能,仅在特殊情况下确实需要时才把 ContainedControls 置为 True。有的控件组合是没有什么意义的,例如,让 Address 控件成为其它控件的容器。

对 ControlContainer 的支持

并非对放置控件的每个容器都能提供 ControlContainer 支持。因为 Visual Basic 窗体支持 ISimpleFrame 接口,而该接口支持 ControlContainer 特性,所以在 Visual Basic 窗体上的控件总能提供该支持。

如果控件实例放置在不支持 ISimpleFrame 的容器上,ControlContainer 支持将是不可用的。控件在其它方面都能正常工作,但却不能往该控件实例上放置其它控件。

为了使 ContainedControls 集合成为可用的,ISimpleFrame 的容器必须实现 IVBGetControls 接口。如果容器没有实现该接口,则在调用该集合的时候就会出错,所以在访问集合的时候应使用错误处理。

注意 开发人员放在有透明背景的容器上的控件是不可见的。要想使该控件成为控件容器,就不要使用透明背景。