3

我有一个使用 MessageBox.Show 显示 MessageBox 的表单,并尝试从 MessageBox 上的“帮助”按钮接收事件,以便我可以执行自己的代码。Microsoft 文档显示了如何执行此操作;但是,使用建议的内容不起作用。这是我的代码的缩短版本:

    Private Function MethodName() As Boolean

      AddHandler Me.HelpRequested, AddressOf Me.MsgBoxHelpRequested
      Select Case MessageBox.Show("Text", "Title", MessageButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2, 0, True)
        Case MsgBoxResult.Yes
          ' Do stuff
        Case MsgBoxResult.No
          ' Do stuff
        Case MsgBoxResult.Cancel
          RemoveHandler Me.HelpRequested, AddressOf Me.MsgBoxHelpRequested
          Return False
      End Select
      RemoveHandler Me.HelpRequested, AddressOf Me.MsgBoxHelpRequested

    End Function

Private Sub MsgBoxHelpRequested(ByVal sender As Object, ByVal hlpevent As System.Windows.Forms.HelpEventArgs)
  ' Breakpoint that never gets hit
  ' More code
End Sub

我一直在寻找解决这个问题的方法,但我发现最好的是这个问题:How to detect Help button press in Windows Forms MessageBox? 这让我回到了似乎不起作用的相同 Microsoft 代码。

有人可以帮我吗?

谢谢你。

4

4 回答 4

2

Me作为第一个参数传递给MessageBox.Show.

将处理程序添加到Form.ActiveForm而不是Me.

于 2010-05-12T21:27:09.533 回答
0

这是 C#,我会在一秒钟内将它自动翻译成 VB。

将此代码放入表单的 Load 事件中:

this.HelpRequested += new HelpEventHandler(Form1_HelpRequested);

然后将此代码添加到您的表单中:

void Form1_HelpRequested(object sender, HelpEventArgs hlpevent)
{
    hlpevent.Handled = true; // this will prevent windows from also opening
        // any associated help file
    // do whatever you're gonna do here
}

然后MessageBox像这样调用:

MessageBox.Show("message", "caption", MessageBoxButtons.OK, 
    MessageBoxIcon.Asterisk,
    MessageBoxDefaultButton.Button1, 0, true);

这将显示一个带有 OK 和 HELP 按钮的消息框。单击 HELP 时,将调用 Form1_HelpRequested。

VB.Net 版本:

将此代码放入表单的 Load 事件中:

AddHandler Me.HelpRequested, AddressOf Form1_HelpRequested 

然后将此代码添加到您的表单中:

Private Sub Form1_HelpRequested(ByVal sender As Object, ByVal hlpevent As 
    HelpEventArgs) 
    ' this will prevent windows from also opening 
    ' any associated help file:
    hlpevent.Handled = True 
    ' do whatever you're gonna do here 
End Sub

然后MessageBox像这样调用:

MessageBox.Show("message", "caption", MessageBoxButtons.OK, 
    MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1, 0, _ 
    True)

这将显示一个带有 OK 和 HELP 按钮的消息框。单击 HELP 时,将调用 Form1_HelpRequested。

于 2010-05-12T21:32:13.850 回答
0

如果您为表单的构造函数(新)或在表单的 Load 事件中调用 MethodName,您的示例代码将不起作用。这可能就是为什么它不适合你。

构造函数是 Sub New。您必须小心构造函数或表单的 Load 事件中的一些初始化。原因是尚未创建包含表单的控件句柄。如果您测试项目有效,则将测试项目与您拥有的项目进行比较。考虑如何调用这些方法以及在哪里调用。您的应用程序无法运行的最可能原因是由于未创建表单而未添加处理程序。(它是在表单变得可见时创建的。您可以尝试在添加处理程序之前添加一个 form.CreateControl。)

此外,尝试通过设计器将处理程序添加到表单中。这将保证处理程序被正确分配。(MSDN 示例手动完成所有操作,并不是一个好的示例。VB 示例应该向您展示如何以简单的 VB 方式完成此操作,而不是更高级的手动方式。)

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Designer-Generated "

    'Form overrides dispose to clean up the component list. 
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub
    Friend WithEvents Button2 As System.Windows.Forms.Button

    'Required by the Windows Form Designer 
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer 
    'It can be modified using the Windows Form Designer.   
    'Do not modify it using the code editor. 
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.Button1 = New System.Windows.Forms.Button
        Me.Button2 = New System.Windows.Forms.Button
        Me.SuspendLayout()
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(0, 0)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(75, 23)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Button1"
        Me.Button1.UseVisualStyleBackColor = True
        '
        'Button2
        '
        Me.Button2.Location = New System.Drawing.Point(0, 29)
        Me.Button2.Name = "Button2"
        Me.Button2.Size = New System.Drawing.Size(75, 23)
        Me.Button2.TabIndex = 1
        Me.Button2.Text = "Button2"
        Me.Button2.UseVisualStyleBackColor = True
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(292, 266)
        Me.Controls.Add(Me.Button2)
        Me.Controls.Add(Me.Button1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)

    End Sub
    Friend WithEvents Button1 As System.Windows.Forms.Button

#End Region

    Public Sub New()
        ' This call is required by the Windows Form Designer. 
        InitializeComponent()
        ' Add any initialization after the InitializeComponent() call. 
        MethodName() 'will not work here 
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        MethodName() 'will not work here 
        'Me.CreateControl()
        MethodName2() 'still will not work 
    End Sub

    Private Function MethodName() As Boolean
        AddHandler Me.HelpRequested, AddressOf Me.MsgBoxHelpRequested
        Select Case MessageBox.Show("Text", "Title", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2, 0, True)
            Case Windows.Forms.DialogResult.Yes
                ' Do stuff  
            Case Windows.Forms.DialogResult.No
                ' Do stuff  
            Case Windows.Forms.DialogResult.Cancel
                RemoveHandler Me.HelpRequested, AddressOf Me.MsgBoxHelpRequested
                Return False
        End Select
        RemoveHandler Me.HelpRequested, AddressOf Me.MsgBoxHelpRequested
    End Function

    Private Function MethodName2() As Boolean
        AddHandler Me.HelpRequested, AddressOf Me.MsgBoxHelpRequested2
        Select Case MessageBox.Show("Text", "Title", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2, 0, True)
            Case Windows.Forms.DialogResult.Yes
                ' Do stuff  
            Case Windows.Forms.DialogResult.No
                ' Do stuff  
            Case Windows.Forms.DialogResult.Cancel
                RemoveHandler Me.HelpRequested, AddressOf Me.MsgBoxHelpRequested2
                Return False
        End Select
        RemoveHandler Me.HelpRequested, AddressOf Me.MsgBoxHelpRequested2
    End Function


    ''' <summary>
    '''  AddHandler Me.HelpRequested, AddressOf Module1.MsgBoxHelpRequested3
    ''' </summary>
    Private Function MethodName3() As Boolean
        AddHandler Me.HelpRequested, AddressOf Module1.MsgBoxHelpRequested3
        Select Case MessageBox.Show("Text", "Title", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button3, 0, True)
            Case Windows.Forms.DialogResult.Yes
                ' Do stuff  
            Case Windows.Forms.DialogResult.No
                ' Do stuff  
            Case Windows.Forms.DialogResult.Cancel
                RemoveHandler Me.HelpRequested, AddressOf Module1.MsgBoxHelpRequested3
                Return False
        End Select
        RemoveHandler Me.HelpRequested, AddressOf Module1.MsgBoxHelpRequested3
    End Function

    Private Sub MsgBoxHelpRequested(ByVal sender As Object, ByVal hlpevent As System.Windows.Forms.HelpEventArgs)
        ' Breakpoint that never gets hit  
        MsgBox("Here I am to save the day!")
    End Sub

    Private Sub MsgBoxHelpRequested2(ByVal sender As Object, ByVal hlpevent As System.Windows.Forms.HelpEventArgs)
        ' Breakpoint that never gets hit  
        MsgBox("Shoot, still now working.")
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        MethodName() 'always works because all handles are created 
    End Sub

    Private Sub Form1_HelpRequested(ByVal sender As System.Object, ByVal hlpevent As System.Windows.Forms.HelpEventArgs) Handles MyBase.HelpRequested
        MsgBox("Always works! No need to add a handler because of Handles MyBase.HelpRequested.")
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        MethodName3()
    End Sub

End Class

Module Module1

    Public Sub MsgBoxHelpRequested3(ByVal sender As Object, ByVal hlpevent As System.Windows.Forms.HelpEventArgs)
        MsgBox("Being handled in a module.")
    End Sub

End Module
于 2010-05-12T23:37:47.233 回答
0

事实证明,除了调用 MessageBox 的窗体之外,还有另一个活动窗口。由于没有任何版本的 MessageBox.Show 允许您同时处理 HelpRequested 事件指定所有者,因此 MessageBox 正在查找 ActiveForm 以获取事件的接收者,而不是将其发送到我的表单。进行以下更改最终使其正常工作:

Private Function MethodName() As Boolean

  Me.Activate() ' <-------------------!!!!!!!!!

  AddHandler Me.HelpRequested, AddressOf Me.MsgBoxHelpRequested
  Select Case MessageBox.Show("Text", "Title", MessageButtons.YesNoCancel, _
            MessageBoxIcon.Question, MessageBoxDefaultButton.Button2, 0, True)
    Case MsgBoxResult.Yes
      ' Do stuff
    Case MsgBoxResult.No
      ' Do stuff
    Case MsgBoxResult.Cancel
      RemoveHandler Me.HelpRequested, AddressOf Me.MsgBoxHelpRequested
      Return False
  End Select
  RemoveHandler Me.HelpRequested, AddressOf Me.MsgBoxHelpRequested
End Function


Private Sub MsgBoxHelpRequested(ByVal sender As Object, _
            ByVal hlpevent As System.Windows.Forms.HelpEventArgs)
  ' Breakpoint that **finally** gets hit
  ' More code
End Sub

我仍将使用与其他事情相关的这段代码来修复许多事情,但最终弄清楚这一点肯定是件好事。

感谢所有帮助过的人。

于 2010-05-13T22:15:41.130 回答