启动时用户窗体中的复选框不起作用

Checkbox in UserForm on startup not working

我有一个带有 2 个下拉菜单的用户窗体,我通常不需要它们,所以我构建了一个复选框并隐藏了下拉菜单和文本标签。默认情况下选中该复选框。但是当我启动用户窗体时,下拉菜单和标签并没有隐藏。当我在用户窗体启动后手动取消选中并选中复选框时,它正在工作。所以我不知道为什么复选框似乎有效,但我需要在每次启动用户窗体后手动 uncheck/check 它。

我想我必须在用户窗体的初始启动时做一些事情?

Private Sub SortCheckBox(blnChecked As Boolean)
Private Sub CheckBox1_Click()
ActiveDocument.Bookmarks("KurbeitragKinder").Range.Font.Hidden = 
CheckBox1.Value
If CheckBox1.Value = True Then
Label8.Enabled = False
Label8.Visible = False
Label9.Enabled = False
Label9.Visible = False
ComboBox6.Enabled = False
ComboBox6.Visible = False
ComboBox7.Enabled = False
ComboBox7.Visible = False
Else
Label8.Enabled = True
Label8.Visible = True
Label9.Enabled = True
Label9.Visible = True
ComboBox6.Enabled = True
ComboBox6.Visible = True
ComboBox7.Enabled = True
ComboBox7.Visible = True
End If
End Sub

UserForm 上的控件首次显示时的状态默认为设计时状态;让我们称之为 "default state".

您可以通过使用设计器的属性工具窗口 (F4) 配置每个控件的单独属性来定义默认状态

如果显示表单的默认实例,则其状态将在调用之间保留:

UserForm1.Show

...除非实例被重置 - 如果您 Unload 该表单,或者如果用户单击红色 "X" 按钮关闭它,这很容易发生:实例被销毁,由于表单有一个预先声明的 ID(又名默认实例),该对象在下次被引用时会自动重新创建 - 无论默认(设计时)状态是什么。如果您处理 QueryClose 事件并在 CloseModeVbQueryClose.vbFormControlMenu 时以编程方式 Hide 表单(并将 Cancel 参数设置为 True,以防止销毁表单实例及其状态),然后将保留状态...这可能会导致意外或不一致的行为。

解决方案是确保始终显示表单的新实例,而不是默认实例:

With New UserForm1
    .Show
End With

这样一来,窗体的状态就保证在每次显示时始终是 default/intended 设计时状态,并且您可以在 .ShowEnd With 之间访问窗体的状态。您需要做的就是处理 QueryClose 并在用户单击 "form control menu" 又名 "the X button".

时取消表单的销毁

初始化表单将引发 Initialize 事件;如果您使用表单的默认实例(即 UserForm1.Show),那么您无法真正控制这种情况何时发生,但如果您每次都显示一个新的实例(即 With New UserForm1),那么您确定每次需要显示表单时都会引发此事件一次。

对象一创建就引发Initialize事件,并且发生在针对它进行第一个成员调用之前(即当New UserForm1returns,事件已经执行)。如果您需要选中一个框 然后 相应地初始化表单,那么您可能想要处理 Activate 事件,该事件将在实际显示表单时引发(即当调用 .Show 方法时):

With New UserForm1 'UserForm_Initialize runs
    .CheckBox1.Value = foo 'form state is accessible here
    .Show 'UserForm_Activate runs
    'UserForm_QueryClose runs
    foo = .CheckBox1.Value 'form state is accessible here
End With 'UserForm_Terminate runs

看起来您想要 运行 在显示表单之前 CheckBox1_Click 处理程序 - 问题是,事件处理程序不是 Public 而您不需要'希望他们成为.

解决方案是将逻辑拉入 Public Sub,从客户端代码调用该过程, 从复选框调用它':

Public Sub InitializeFormState()
    Dim isChecked As Boolean
    isChecked = CheckBox1.Value
    ActiveDocument.Bookmarks("KurbeitragKinder") _
                  .Range.Font.Hidden = isChecked
    Label8.Enabled = isChecked
    Label8.Visible = isChecked
    Label9.Enabled = isChecked
    Label9.Visible = isChecked
    ComboBox6.Enabled = isChecked
    ComboBox6.Visible = isChecked
    ComboBox7.Enabled = isChecked
    ComboBox7.Visible = isChecked
End Sub

Private Sub CheckBox1_Click()
    InitializeFormState
End Sub

现在您的客户端代码可以如下所示:

With New UserForm1
    .InitializeFormState
    .Show
    'consume form state here
End With

或者,您可以根据需要从表单的 InitializeActivate 处理程序中调用 InitializeFormState

Private Sub UserForm_Initialize()
    InitializeFormState
End Sub

Private Sub UserForm_Activate()
    InitializeFormState
End Sub

在这种情况下,可能应该制作过程 Private,并且不需要在 .Show 方法之前从客户端代码调用它。