将框架内的控件事件连接到 FrameGroup 类

Connecting events of controls inside frame to FrameGroup classes

我有一个用户窗体,它从文件中读取数据并动态地用其他框架控件填充框架控件,这些框架控件本身填充有描述该数据的标签。因此,有一个大的框架控件——DisplayFrame——使用工具箱放在用户窗体上,并且在运行时当文件打开时,其他较小的框架控件——cFrame1、cFrame2 等——被添加到 DisplayFrame 控件中,带有 NameLabel、DateLabel 等标签, 添加到每个 cFrame.

我希望用户能够 select 任何 cFrame,然后单击用户表单上的一个按钮,然后单击另一个 window 以打开其中的所有数据该 cFrame 中的标签(加上附加数据)。

select,我的意思是,当用户点击特定 cFrame 内的任何标签时——或 cFrame 本身——cFrame 及其所有元素的颜色都会发生变化,并且会记录该特定 cFrame作为当前的 selection。我认为棘手的部分是任何以前 selected cFrame 的颜色应该变回默认颜色。

我创建了一个名为 FrameGroup 的 Class 来保存所有创建的 cFrame。我定义了 FrameGroup class 的点击事件,当它被 selected 时改变颜色,并保存 cFrame 的数据只是 selected.

<<Class FrameGroup>>
Public WithEvents FrameGroup As Frame

Private cName As String
Private cDay As String

Private Sub FrameGroup_Click()
    cName = FrameGroup.Controls(0).Caption
    cDay = FrameGroup.Controls(1).Caption

    ' If current cFrame was selected before, then deselect it 
    ' by returning to default color
    If FrameGroup.BackColor = &H8000000D Then
        FrameGroup.BackColor = &H80000005
        FrameGroup.Controls(0).BackColor = &H80000005
        FrameGroup.Controls(1).BackColor = &H80000005
    Else
       ' Select cFrame by changing color
        FrameGroup.BackColor = &H8000000D
        FrameGroup.Controls(0).BackColor = &H8000000D
        FrameGroup.Controls(1).BackColor = &H8000000D
    End If
End Sub
<<Code for UserForm>>
Dim FrameList() As New FrameGroup

Private Sub UserForm_Initialize()
    Dim TextLine As String
    Dim Text() As String
    Dim LineNo As Integer

    ' Open file containing saved Color Scales
    Open file For Input As #1

    LineNo = 0
    Do Until EOF(1)
        Line Input #1, TextLine
        Text = Split(TextLine, ",")

        ' Making CFrame
        Dim currCFrame As Frame
        Set currCFrame = DisplayFrame.Controls.Add("Forms.Frame.1", "cFrame" & LineNo, True)

        ' Adding labels
        Dim NameLabel As Control
        Set NameLabel = currCFrame.Controls.Add("Forms.Label.1", "Name" & LineNo, True)
        Dim DateLabel As Control
        Set DateLabel = currCFrame.Controls.Add("Forms.Label.1", "DateCreated" & LineNo, True)

        ' Increment line number
        LineNo = LineNo + 1

        ' Adding new frame to frame group
        ReDim Preserve FrameList(1 To LineNo + 1)
        Set FrameList(LineNo).FrameGroup = currCFrame

    Loop

    ' Close file once we are done reading color scales from it
    Close #1


End Sub

发生的情况是,只有单击 cFrame 时才会发生任何事情——单击其中的任何标签时不会发生任何事情。而且我不知道如何做到当点击一个cFrame时,之前selected cFrame的颜色也被更改为默认颜色。

我试图查找如何做这样的事情,像 this 这样的解决方案似乎为 cFrame 及其标签和中介 [=27] 提出了一个不同的 class 模块=] 处理两个 classes 之间的通信,但这看起来很复杂。如果我遵循这种设计,我可能需要在 cFrame 和被单击以加载数据的按钮之间使用另一个中介,对吗?我不想让它变得比它需要的更复杂,但我也想创建一个可持续和强大的解决方案。任何帮助将不胜感激。

Frame 控件的 Click 事件只有在您单击该框架的边框或其 空白区域 时才会引发。如果您单击 Frame 中的 Label,此控件有其自己的区域。如果您单击此区域,则会引发标签的 Click 事件,而不是框架的。

下图显示属于 Label(灰色)的区域与属于 Frame(红色)的区域。

Label Click 放入并点击另一个框架给其他框架默认颜色, 尽量减少对以下代码的调整:

  '<<Class FrameGroup>>
    Public WithEvents FrameGroup As MSForms.Frame
    Public WithEvents LabelGroup As MSForms.Label
    Private cName As String
    Private cDay As String

    Private Sub FrameGroup_Click()
    Dim ctl As MSForms.Control
        cName = FrameGroup.Controls(0).Caption
        cDay = FrameGroup.Controls(1).Caption
         For Each ctl In FrameGroup.Parent.Controls
            ctl.BackColor = &H80000005
         Next
            FrameGroup.BackColor = &H8000000D
            FrameGroup.Controls(0).BackColor = &H8000000D
            FrameGroup.Controls(1).BackColor = &H8000000D
    End Sub

    Private Sub LabelGroup_Click()
    Dim ctl As MSForms.Control
        cName = LabelGroup.Parent.Controls(0).Caption
        cDay = LabelGroup.Parent.Controls(1).Caption
        For Each ctl In LabelGroup.Parent.Parent.Controls
            ctl.BackColor = &H80000005
        Next
            LabelGroup.Parent.BackColor = &H8000000D
            LabelGroup.Parent.Controls(0).BackColor = &H8000000D
            LabelGroup.Parent.Controls(1).BackColor = &H8000000D
    End Sub


    '<<Code for UserForm>>
    Dim FrameList() As New FrameGroup

    Private Sub UserForm_Initialize()
        Dim TextLine As String
        Dim Text() As String
        Dim LineNo As Integer

        ' Open file containing saved Color Scales
       Open file For Input As #1

        LineNo = 0
        Do Until EOF(1)
            Line Input #1, TextLine
            Text = Split(TextLine, ",")

            ' Making CFrame
            Dim currCFrame As Frame
            Set currCFrame = DisplayFrame.Controls.Add("Forms.Frame.1", "cFrame" & LineNo, True)

            ' Adding labels
            Dim NameLabel As Control
            Set NameLabel = currCFrame.Controls.Add("Forms.Label.1", "Name" & LineNo, True)
            Dim DateLabel As Control
            Set DateLabel = currCFrame.Controls.Add("Forms.Label.1", "DateCreated" & LineNo, True)

            ' Increment line number
            LineNo = LineNo + 1

            ' Adding new controls to frame group
            ReDim Preserve FrameList(1 To 3 * (LineNo + 1))
            Set FrameList(3 * (LineNo) + 1).FrameGroup = currCFrame
            Set FrameList(3 * (LineNo) + 2).LabelGroup = DateLabel
            Set FrameList(3 * (LineNo) + 3).LabelGroup = NameLabel

        Loop

        ' Close file once we are done reading color scales from it
        Close #1

    End Sub