Флажок в UserForm при запуске не работает - PullRequest
1 голос
/ 25 марта 2019

У меня есть пользовательская форма с двумя выпадающими меню, которые мне обычно не нужны, поэтому я создаю флажок и скрываю выпадающее меню и текстовую метку.Флажок установлен по умолчанию.Но выпадающий список и метка не скрываются при запуске пользовательской формы.Когда я вручную снимаю флажок и ставлю флажок после запуска UserForm, он работает.Поэтому я не знаю, почему флажок работает, но мне нужно снимать / проверять его вручную после каждого запуска пользовательской формы.

Я думаю, что должен что-то делать при первоначальном запуске пользовательской формы?

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

1 Ответ

0 голосов
/ 25 марта 2019

Состояние элементов управления на UserForm при его первом отображении будет, по умолчанию, независимо от состояния времени разработки;давайте назовем это «состоянием по умолчанию».

Вы можете определить, что это состояние по умолчанию , настроив отдельные свойства каждого элемента управления, используя properties toolwindow дизайнера (F4).

Если в форме экземпляр по умолчанию показан, то его состояние будет сохраняться между вызовами:

UserForm1.Show

... если экземпляр не будет сброшен - что можетэто легко случится, если вы Unload эту форму или пользователь нажмет красную кнопку «Х», чтобы закрыть ее: экземпляр уничтожен, а поскольку формы имеют предварительно объявленный идентификатор (он же экземпляр по умолчанию), объект автоматически воссоздаетсяв следующий раз на него ссылаются - каким бы ни было состояние по умолчанию (время разработки).Если вы обрабатываете событие QueryClose и программно Hide форму, когда CloseMode равно VbQueryClose.vbFormControlMenu (и для параметра Cancel установлено значение True, чтобы предотвратить уничтожение экземпляра формы и еесостояние), то состояние будет сохранено ... и это может привести к непредвиденному или противоречивому поведению.

Решение состоит в том, чтобы всегда отображать новый экземпляр формы вместо стандартного:

With New UserForm1
    .Show
End With

Таким образом, состояние формы гарантированно всегда будет заданным по умолчанию / предполагаемым временем разработки каждый раз, когда оно отображается, и вы можете получить доступ к состоянию формы между .Show и End With.Все, что вам нужно сделать, это обработать QueryClose и отменить уничтожение формы, когда пользователь нажимает «меню управления формой» или «кнопку X».

Инициализация формы вызовет событие Initialize;если вы используете экземпляр формы по умолчанию (например, UserForm1.Show), тогда вы не сможете точно контролировать, когда это произойдет, но если вы будете каждый раз показывать новый экземпляр (например, With New UserForm1), то вы уверены, чтоэто событие будет вызвано ровно один раз, каждый раз, когда вам нужно показать форму.

Событие Initialize возникает, как только объект создан, и это происходит до того, как первый вызов члена будет сделан для него.(т.е. когда New UserForm1 возвращается, событие уже выполнено).Если вам нужно установить флажок , а затем инициализировать форму соответствующим образом, вы можете вместо этого обработать событие 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

Или, при необходимости, вы можете вызывать InitializeFormState из обработчика Initialize или Activate формы:

Private Sub UserForm_Initialize()
    InitializeFormState
End Sub

или

Private Sub UserForm_Activate()
    InitializeFormState
End Sub

В этом случае процедуру, вероятно, следует выполнить Private, и нет необходимости вызывать ее из кода клиента перед методом .Show.

...