保存 ShapeLabel 控件的属性值

与在类模块中添加属性名和方法类似,借助创建公共过程的方式,可以在 Active 控件中添加属性和方法。由于 ShapeLabel 将成为一个增强的有标题控件,所以具有 Caption 属性将是很有意义的。

下列过程添加一个 Caption 属性和用于存取属性值的支持代码。控件的属性值一直是和描述容器的其它描述容器的数据一起保存,本例中是 Form1。

注意   本主题是演示创建示例性 ActiveX 控件一系列步骤中的一部分。它是从创建 ActiveX 控件开始。

要在 ShapeLabel 控件中添加 Caption 属性,请按照以下步骤执行:

  1. 在“工程资源管理器”窗口双击“ShapeLabel”打开其设计器,再双击“ShapeLabel”使其代码窗口置前。

  2. 在“工具”菜单上单击“添加过程”打开“添加过程”对话框。在“名称”框输入名字 Caption。 单击“属性”和“公共的”后再单击“确定”。

  3. 在代码窗口更改新创建的属性过程为如下所述。
    Public Property Get Caption() As String
    Caption = lblCaption.Caption
    End Property
    
    Public Property Let Caption( _
    ByVal NewCaption As String)
    lblCaption.Caption = NewCaption
    PropertyChanged "Caption"
    End Property
    

    注意   如上所示,在加入 As String 时要注意同时更改两个声明行。Property Get 和 Property Let 声明必须匹配。使用特定的类型名可加快执行速度,并且能为使用控件的开发者提供类型检查。

    无论何时给 Caption 属性赋新值 Property Let 过程都将执行。 它把新值直接保存到 ShapeLabel 上的 lblCaption 选项卡的 Caption 属性中。

    无论何时读取该属性值均执行 Property Get 过程。它要读取保存在 lblCaption 选项卡的 Caption 属性中的该值。

    如“建立 ActiveX 控件”中的“给控件添加属性”所述,控件中的 Property Let 过程必须调用 PropertyChanged 。这就告诉“属性”窗口刷新其显示内容,并通知 Visual Basic ,窗体已经改变了。

    Property 过程的讨论可在《Visual Basic 程序员指南》的 “用对象编程”中的“给类添加属性”部分找到。

  4. 为了初始化 Caption 属性,在 UserControl_InitProperties 事件过程中添加下列代码:
    Private Sub UserControl_InitProperties()
    ' ShapeLabel 实例的名字
    '赋给 Caption 属性
    '作为它的初始值。
    Caption = Extender.Name
    Debug.Print "InitProperties"
    End Sub
    

    该例中的 Extender 对象是什么? 对控件用户而言,extender 属性同 Name 、Top 和 Left 属性一样,是用户控件的一部分。 实际上 extender 属性是由控件所属的容器对象提供的。UserControl 的 Extender 对象使得控件设计器能够从控件内部访问这些属性。

    Extender 对象的只读的 Name 属性返回容器(或用户)赋予控件的特定实例的名字。用这个名字(例如,ShapeLabel1)作为 Caption 属性初值来模仿 Label 控件的行为。

提示   如果控件要模仿一个提供类似功能的控件,那么用它会更加直观。

当为控件创建 Name 属性会发生什么事情?将能够从控件内部访问它,但用户所能看见的 Name 属性只是 Extender 对象的 Name 属性。

这就引入了一个控件的重复主题:容器能决定控件的大部分行为和外观。 容器确定控件的 Name,以及保持相对容器坐标关系的 Top 和 Left 属性。“建立 ActiveX 控件”会再次提出主题。

最后:为什么要把这些代码放在 InitProperties 事件中? 为什么不使用 Initialize 事件呢?如同所见,每当控件实例被创建时均调用 Initialize,它是频繁引发的。而 InitProperties 是仅当用户把控件放入容器时才被引发。此时设置控件实例的初值较为合适。

此外当 Initialize 事件引发时,UserControl 对象的 Extender 和 AmbientProperties 对象尚且不能使用。 “建立 ActiveX 控件”中的“理解控件的存活期和关键事件”部分将讨论 Initialize 事件的恰当用法。

  1. 要保存 Caption 属性值,可把下列代码添加到 UserControl_WriteProperties 事件过程中:
    Private Sub UserControl_WriteProperties(PropBag As _
    PropertyBag)
    Debug.Print "WriteProperties"
    PropBag.WriteProperty "Caption", Caption, _
    Extender.Name
    End Sub
    

    PropertyBag 意如其名,是一个保存属性值的口袋。 该口袋由容器提供。用户无法了解它的工作原理,以及数据在何处以及是怎样保存的。 所做的全部事情就是放入值和取出值。

    WriteProperty 方法的第一个参数是属性名,它将作为检索键使用。 应使用属性名作为这个参数,因为它将出现在 .frm 文本文件中(在 Visual Basic 中,其它容器可能使用别的文件名来保存工程数据),而且对于该控件的用户是可见的。

    第二个参数是值。 属性值作为一个 Variant 被保存。

    第三个参数很特别,是一个缺省值。 保存属性值时为什么要提供一个缺省值呢? 在保存该值之前,WriteProperty 方法要用此缺省值和属性值作比较。 若二者相同,则该属性值就不必保存,因为当控件重新加载时会自动装入此缺省值。 这样就避免了使 .frm 文件中数百个缺省条目混杂,对用户来说是十分有利的!

  2. 将下列代码放入 ReadProperties 事件中,可用来读取 Caption 属性的持久值。
    Private Sub UserControl_ReadProperties(PropBag As _
    PropertyBag)
    Debug.Print "ReadProperties"
    Caption = PropBag.ReadProperty("Caption", _
    Extender.Name)
    End Sub
    

    当如果没有保存任何值时,ReadProperty 方法的第二个参数使用缺省值,如果用户已从文本文件删除了该属性,或者如果从未改变过这个缺省值,自然也就从未通过 WriteProperty 保存过它。

  3. 确保 ShapeLabel 的设计器在最前,然后按下“关闭”按钮或 CTRL+F4 以关闭窗口,使控件进入运行模式。 ShapeLabel 控件的标题会发生改变以匹配两个实例的缺省名字 ShapeLabel1 和 ShapeLabel2。

    使用“属性”窗口改变 Form1 上的两个 ShapeLabel 控件的“标题”属性,然后单击 Form1 设计器的“关闭”按钮。 在“工程资源管理器”窗口双击“Form1”重新打开 Form1 设计器。

    从“立即”窗口的消息中可以看见控件已经被撤消和重建,但“标题”属性值已被保存及检索。

  4. 按下 CTRL+F5 键以运行 TestCtlDemo,即工程组的 Startup 工程,并观察 ShapeLabel 控件在运行时期的行为。

  5. 单击 Form1 的“关闭”按钮以返回到设计模式。

详细信息 关于保存和检索属性值的细节,请参阅“建立 ActiveX 控件”中的“在控件中添加属性”部分。 同一章的“显露子控件属性”部分解释了 ActiveX 控件界面向导怎样简化了保存和检索属性值这部分代码的编写工作。

步骤

本主题是演示创建示例性 ActiveX 控件一系列步骤中的一部分。

请参阅
转到下一步 为 ShapeLabel 控件添加一个属性页
从头启动 创建 ActiveX 控件