VBA поднимает события от немодального пользователя из - PullRequest
1 голос
/ 15 марта 2020

Я пытаюсь вызвать события от немодальной формы пользователя. Моя отправная точка - , это отличный пример . Когда я показываю форму немодально , код, вызывающий событие, выполняется, но обработчик события никогда не запускается (я не получаю ожидаемый MsgBox при нажатии кнопки Отмена.) Когда я показываю форму modal , события обрабатываются по желанию, но форма больше не является немодальной по желанию.

Форма пользователя с именем FormWithEvents имеет OKButton и CancelButton; вот код:

Option Explicit

Public Event FormConfirmed()
Public Event FormCancelled(ByRef Cancel As Boolean)

Private Function OnCancel() As Boolean
    Dim cancelCancellation As Boolean
    RaiseEvent FormCancelled(cancelCancellation)
    If Not cancelCancellation Then Me.Hide
    OnCancel = cancelCancellation
End Function

Private Sub CancelButton_Click()
    OnCancel
End Sub

Private Sub OKButton_Click()
    Me.Hide
    RaiseEvent FormConfirmed
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = VbQueryClose.vbFormControlMenu Then
        Cancel = Not OnCancel
    End If
End Sub

Вот код класса Presenter, который показывает форму:

Option Explicit
Private WithEvents myModelessForm As FormWithEvents

Public Sub Show()
    Set myModelessForm = New FormWithEvents
    ' COMMENT OUT ONE OF THE FOLLOWING TWO LINES TO TOGGLE MODELESS OR MODAL
    myModelessForm.Show vbModeless  ' Modeless, but events don't get handled (no msgbox on clicking cancel button)
    ' myModelessForm.Show vbModal     ' Events get handled, but no longer modal
End Sub

Private Sub myModelessForm_FormCancelled(Cancel As Boolean)
    ' Setting cancel to True will leave the form open
    Cancel = MsgBox("Cancel this operation?", vbYesNo + vbExclamation) = vbNo
    If Not Cancel Then
        ' Modeless form was cancelled and is now hidden
        ' ...
        Set myModelessForm = Nothing
    End If
End Sub


Private Sub myModelessForm_FormConfirmed()
    ' Form was okayed and is now hidden
    Set myModelessForm = Nothing
End Sub

А вот код в основном модуле:

Option Explicit

Public Sub RunForm()
    With New Presenter
        .Show
    End With
End Sub

Есть идеи, где я ошибся?

Ответы [ 2 ]

1 голос
/ 15 марта 2020

Может быть, вместо этого вы можете сохранить экземпляр Presenter в области видимости:

Dim pres as Presenter

Public Sub RunForm()
    Set pres =  New Presenter
    pres.Show
End Sub
0 голосов
/ 15 марта 2020

Избегайте использования RaiseEvent. Объявите публикуемый c экземпляр класса Presenter в стандартном модуле. Параметр Явный

Public Preter As New Presenter

Public Sub RunForm()

    With New Presenter
        .Show
    End With
End Sub

Преобразование процедуры события в подпрограмму с помощью publi c scope.

Sub FormCancelled(Cancel As Boolean)
    ' Setting cancel to True will leave the form open
    Cancel = MsgBox("Cancel this operation?", vbYesNo + vbExclamation) = vbNo
    If Not Cancel Then
        ' Modeless form was cancelled and is now hidden
        ' ...
        Set myModelessForm = Nothing
    End If
End Sub

Вызов подпрограммы в классе.

Private Function OnCancel() As Boolean

    Dim cancelCancellation As Boolean

    Preter.FormCancelled cancelCancellation
    If Not cancelCancellation Then Me.Hide

    OnCancel = cancelCancellation
End Function

Я не уверен, но ваша строка кода Set myModelessForm = Nothing в модуле класса беспокоит меня. Интересно, следует ли вместо этого скрывать форму, чтобы код мог перейти к процедуре Show, где форма затем может быть помещена в состояние покоя.

...