简单的对话框,如带自定义按钮的 msgbox (vb)

问题描述 投票:0回答:3

我想询问用户“你想向右走还是向左走?”。
为了获得简单的代码,我使用 MSGBOX 并带有如下提示:

“你想向右走还是向左走”

按“YES 表示‘右’/NO 表示‘左’”

然后我处理按下的是/否/取消。这可行,但很丑陋,在某些情况下很难理解。

此外,在某些情况下,我有超过 2 个选择 - 但这可能是另一个问题......

vb.net
3个回答
6
投票

您可以动态创建一个

Public Module CustomMessageBox
    Private result As String
    Public Function Show(options As IEnumerable(Of String), Optional message As String = "", Optional title As String = "") As String
        result = "Cancel"
        Dim myForm As New Form With {.Text = title}
        Dim tlp As New TableLayoutPanel With {.ColumnCount = 1, .RowCount = 2}
        Dim flp As New FlowLayoutPanel()
        Dim l As New Label With {.Text = message}
        myForm.Controls.Add(tlp)
        tlp.Dock = DockStyle.Fill
        tlp.Controls.Add(l)
        l.Dock = DockStyle.Fill
        tlp.Controls.Add(flp)
        flp.Dock = DockStyle.Fill
        For Each o In options
            Dim b As New Button With {.Text = o}
            flp.Controls.Add(b)
            AddHandler b.Click,
                Sub(sender As Object, e As EventArgs)
                    result = DirectCast(sender, Button).Text
                    myForm.Close()
                End Sub
        Next
        myForm.FormBorderStyle = FormBorderStyle.FixedDialog
        myForm.Height = 100
        myForm.ShowDialog()
        Return result
    End Function
End Module

您会看到可以选择显示哪些按钮、消息和标题。

像这样使用它

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim result = CustomMessageBox.Show(
            {"Right", "Left"},
            "Do you want to go right or left?",
            "Confirm Direction")
        MessageBox.Show(result)
    End Sub
End Class

在我的示例中,提示符为

"Do you want to go right or left?"
,选项为
"Right"
"Left"

返回字符串而不是 DialogResult,因为现在您的选项是无限的(!)。尝试适合您的套装的尺寸。


2
投票
  1. 您需要根据您的需要创建自己的“自定义”消息框表单,最好创建一个可重用的控件 - 通过自定义控件的构造函数传递您的“问题”字符串。
  2. 您需要一些“方法”来从自定义消息框外部获取用户决策 - 一种方法是使用
    DialogResult
    枚举。

这是我刚刚编写的一个基本示例来演示这一点,请参阅我在代码中添加的注释。


创建一个包含 2 个表单的新项目,Form1 将是调用自定义 msgbox 的主表单,Form2 将是自定义 msgbox:

表格1:

表格2:

表格1代码:

Public Class Form1
    Private Sub btnOpenCustomMsgbox_Click(sender As Object, e As EventArgs) Handles btnOpenCustomMsgbox.Click
        Dim customMsgbox = New Form2("this is my custom msg, if you press yes i will do something if you press no i will do nothing")
        If customMsgbox.ShowDialog() = DialogResult.Yes Then
            ' do something
            MsgBox("I am doing some operation...")
        Else
            ' do nothing (its DialogResult.no)
            MsgBox("I am doing nothing...")
        End If
    End Sub
End Class

表格2代码:

Public Class Form2

    ' field that will contain the messege
    Private PromtMsg As String
    Sub New(ByVal promtmsg As String)

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        ' set global field with the argument that was passed to the constructor
        Me.PromtMsg = promtmsg
    End Sub

    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' set the msg label
        Me.lblPromtMsg.Text = Me.PromtMsg
    End Sub

    Private Sub btnCustomYes_Click(sender As Object, e As EventArgs) Handles btnCustomYes.Click
        ' user choosed yes - return DialogResult.Yes
        Me.DialogResult = DialogResult.Yes
        Me.Close()
    End Sub

    Private Sub btnCustomNo_Click(sender As Object, e As EventArgs) Handles btnCustomNo.Click
        ' user choosed no - DialogResult.no
        Me.DialogResult = DialogResult.No
        Me.Close()
    End Sub

End Class

它可能要复杂得多,但如果你探索这个例子,我希望你能理解总体思路。


0
投票

我创建了自己的自定义类,它使用从代码创建的表单重新创建对话框,而不是通过 Visual Studio 的 UI 构建它。您可以在项目中创建一个新类,将其命名为“Msg”,然后使用以下代码:

类内的函数是

Show(“字符串,或RTFEncodedString”,可选按钮,可选图标,可选标题,可选宽度,可选高度,可选DurationMs,可选背景颜色,可选图片框)

所以至少,你会:

Msg.Show(“你好世界”)

与 msgbox("hello world") 或 message.show("hello world") 非常相似

而且,MsgBox() 比 message.show 更受限制 - 因为后者可以有图标,但仅此而已。

而我的班级 Msg.Show() 可以有各种这样的:

对于 600 x 300 对话框,带有“是”、“否”取消按钮和信息图标,并将显示 5000 毫秒

Msg.Show("hello world", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information, "标题文本", 600, 300, 5000)

相同,但要无限期地显示,只需将持续时间设置为 0

Msg.Show("hello world", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information, "标题文本", 600, 300, 0)

也想改变背景颜色吗?

Msg.Show("hello world", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information, "标题文本", 600, 300, 5000, color.lightBlue)

想要添加图形吗?截图/图像?

Msg.Show("hello world", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information, "标题文本", 600, 300, 5000, color.lightBlue, examplePicturebox)

代码如下:

Imports System.Windows.Forms
Imports System.Drawing

Public Class msg
    Private Shared _result As DialogResult
    Private Shared _formWidth As Integer = 400
    Private Shared _formHeight As Integer = 250
    Private Shared _timer As Timer
    Private Shared _duration As Integer
    Private Shared isTimerRunning As Boolean = False
    Private Shared useDynamicHeight As Boolean = False

    Public Shared minimumDialogWidth As Integer = 400
    Public Shared minimumDialogHeight As Integer = 180
    Public Shared maximumDialogWidth As Integer = 1500
    Public Shared maximumDialogHeight As Integer = 1000

    Public Shared selectedBackColour As Color = SystemColors.Control
    Public Shared ReplaceThisWithYourOwnImage As New PictureBox

    Public Shared Function Show(message As String, Optional buttons As MessageBoxButtons = MessageBoxButtons.OK, Optional icon As MessageBoxIcon = MessageBoxIcon.None, Optional title As String = "", Optional dialogWidth As Integer = 400, Optional dialogHeight As Integer = 250, Optional durationMilliseconds As Integer = 0, Optional backColor As Color? = Nothing, Optional ByVal graphics As PictureBox = Nothing) As DialogResult
    _result = DialogResult.None ' Reset _result
    Dim _form As New Form()
    Dim actualBackColor As Color = If(backColor.HasValue, backColor.Value, SystemColors.Control)
    Dim _rtbTitle As New RichTextBox()
    Dim _rtbMessage As New RichTextBox()
    Dim _btnYes As New Button()
    Dim _btnNo As New Button()
    Dim _btnCancel As New Button()
    Dim _btnOK As New Button()

    Dim _title As String = title
    Dim _message As String = message
    Dim _buttons As MessageBoxButtons = buttons
    Dim _icon As MessageBoxIcon = icon

    Try
        ' check for minimum & maximum values
        If dialogWidth < minimumDialogWidth Then
            dialogWidth = minimumDialogWidth
        End If

        If dialogHeight < minimumDialogHeight Then
            dialogHeight = minimumDialogHeight
        End If

        If dialogWidth > maximumDialogWidth Then
            dialogWidth = maximumDialogWidth
        End If

        If dialogHeight > maximumDialogHeight Then
            dialogHeight = maximumDialogHeight
        End If
    Catch ex As Exception
        ' SUPRESS
    End Try

    Dim _formWidth As Integer = dialogWidth
    Dim _formHeight As Integer = dialogHeight
    Dim _duration As Integer = durationMilliseconds

    ' If Duration has been set, meaning timer will be enabled, set the flag to TRUE
    If _duration > 0 Then
        isTimerRunning = True
    End If

    ' Initialize the Form and its Controls
    InitializeForm(_form, _rtbTitle, _rtbMessage, _btnYes, _btnNo, _btnCancel, _btnOK, _title, _message, _buttons, _icon, _formWidth, _formHeight, _duration, actualBackColor, graphics)

    Try
        ' Show the Form
        _form.ShowDialog()
    Catch ex As Exception
        ' SUPRESS
    End Try

    Return _result
End Function

Private Shared Sub InitializeForm(ByRef _form As Form, ByRef _rtbTitle As RichTextBox, ByRef _rtbMessage As RichTextBox, ByRef _btnYes As Button, ByRef _btnNo As Button, ByRef _btnCancel As Button, ByRef _btnOK As Button, title As String, message As String, buttons As MessageBoxButtons, icon As MessageBoxIcon, dialogWidth As Integer, dialogHeight As Integer, duration As Integer, backColor As Color, Optional ByVal pictureBox As PictureBox = Nothing)
    _form = New Form()
    _form.FormBorderStyle = FormBorderStyle.FixedDialog
    _form.StartPosition = FormStartPosition.CenterScreen
    _form.Width = dialogWidth
    _form.Height = dialogHeight

    _form.BackColor = backColor
    _form.MinimizeBox = False
    _form.MaximizeBox = False
    _form.Text = title
    _form.TopMost = True

    ' Icon Parameters
    Dim iconPictureBox As New PictureBox()
    iconPictureBox.SizeMode = PictureBoxSizeMode.StretchImage
    iconPictureBox.Width = 32
    iconPictureBox.Height = 32
    iconPictureBox.Location = New Point(10, 10)

    Select Case icon
        Case MessageBoxIcon.Information
            iconPictureBox.Image = SystemIcons.Information.ToBitmap()
            _rtbTitle.ForeColor = Color.Black

        Case MessageBoxIcon.Warning Or MessageBoxIcon.Exclamation
            iconPictureBox.Image = SystemIcons.Warning.ToBitmap()
            _rtbTitle.ForeColor = Color.Black

        Case MessageBoxIcon.Error Or MessageBoxIcon.Hand
            iconPictureBox.Image = SystemIcons.Error.ToBitmap()
            _rtbTitle.ForeColor = Color.Red

        Case MessageBoxIcon.Question
            iconPictureBox.Image = SystemIcons.Question.ToBitmap()
            _rtbTitle.ForeColor = Color.Black

        Case Else
            ' No icon
            _rtbTitle.ForeColor = Color.Black
            iconPictureBox.Width = 0
    End Select

    ' Add Icon To the Form 
    _form.Controls.Add(iconPictureBox)

    Dim rtbPadding As Integer = 35
    Dim buttonPadding As Integer = 10
    Dim buttonHeight As Integer = 25

    ' RichTextBox Parameters
    _rtbTitle.Text = title
    _rtbTitle.Font = New Font("Calibri", 14, FontStyle.Regular)
    _rtbTitle.ReadOnly = True
    _rtbTitle.Enabled = True
    _rtbTitle.BackColor = _form.BackColor
    _rtbTitle.BorderStyle = BorderStyle.None
    _rtbTitle.Width = _form.Width - iconPictureBox.Width - rtbPadding - buttonPadding
    _rtbTitle.Height = 30
    If iconPictureBox.Width > 0 Then
        _rtbTitle.Location = New Point(iconPictureBox.Width + 20, 15) ' Set the location
    Else
        _rtbTitle.Location = New Point(10, 15) ' Set the location
    End If

    ' Add the RichTextBox To the Form 
    _form.Controls.Add(_rtbTitle)

    _rtbMessage.Rtf = ConvertPlainTextToRTF(message)
    '_rtbMessage.Font = New Font("Calibri", 10.5, FontStyle.Regular)
    _rtbMessage.ReadOnly = True
    _rtbMessage.Enabled = True
    _rtbMessage.BackColor = _form.BackColor
    _rtbMessage.WordWrap = True
    _rtbMessage.BorderStyle = BorderStyle.None
    _rtbMessage.Width = _form.Width - rtbPadding

    ' Calculate Height based on message length
    Dim lineHeight As Integer = TextRenderer.MeasureText("Text", _rtbMessage.Font).Height
    Dim lines As Integer = _rtbMessage.GetLineFromCharIndex(_rtbMessage.TextLength) + 1
    Dim requiredHeight As Integer = lineHeight * lines + lineHeight
    _rtbMessage.Height = Math.Min(requiredHeight, maximumDialogHeight)
    _rtbMessage.Location = New Point(10, iconPictureBox.Height + 20) ' Set the location
    _rtbMessage.ScrollBars = ScrollBars.Both
    ' Add the RichTextBox To the Form 
    _form.Controls.Add(_rtbMessage)

    ' PictureBox Parameters - For optional Graphics 
    Dim heightAdjustment As Integer = 0
    If pictureBox IsNot Nothing Then
        heightAdjustment += (_form.Width / 9) * 4
        pictureBox.Width = _rtbMessage.Width
        pictureBox.Height = heightAdjustment
        heightAdjustment += buttonPadding * 2
        ' _form.Height += heightAdjustment + buttonPadding
        pictureBox.BackColor = Color.Transparent
        pictureBox.SizeMode = PictureBoxSizeMode.StretchImage
        pictureBox.Location = New Point(10, _rtbMessage.Bottom + buttonPadding) ' Position below _rtbMessage
        _form.Controls.Add(pictureBox)
    End If

    _form.Height = _rtbMessage.Bottom + 80 + heightAdjustment

    ' Buttons
    Dim buttonWidth As Integer = 80
    Dim buttonMargin As Integer = 10
    Dim startX As Integer = (_form.Width - (buttonWidth + buttonMargin) - buttonPadding * 2)
    Dim startY As Integer = _form.Height - buttonHeight - (buttonPadding * 2) - 30
    If buttons = MessageBoxButtons.YesNo Then
        Dim btnYes As New Button()
        InitializeButton(btnYes, "Yes", startX, startY, buttonWidth, buttonHeight, AddressOf YesClick, _form)
        startX -= buttonWidth + buttonMargin
        btnYes.Select()
        Dim btnNo As New Button()
        InitializeButton(btnNo, "No", startX, startY, buttonWidth, buttonHeight, AddressOf NoClick, _form)
        startX -= buttonWidth + buttonMargin
    ElseIf buttons = MessageBoxButtons.OKCancel Then
        Dim btnOK As New Button()
        InitializeButton(btnOK, "OK", startX, startY, buttonWidth, buttonHeight, AddressOf OKClick, _form)
        startX -= buttonWidth + buttonMargin
        btnOK.Select()
        Dim btnCancel As New Button()
        InitializeButton(btnCancel, "Cancel", startX, startY, buttonWidth, buttonHeight, AddressOf CancelClick, _form)
        startX -= buttonWidth + buttonMargin
    ElseIf buttons = MessageBoxButtons.OK Then
        Dim btnOK As New Button()
        InitializeButton(btnOK, "OK", startX, startY, buttonWidth, buttonHeight, AddressOf OKClick, _form)
        startX -= buttonWidth + buttonMargin
        btnOK.Select()
    ElseIf buttons = MessageBoxButtons.YesNoCancel Then
        Dim btnYes As New Button()
        InitializeButton(btnYes, "Yes", startX, startY, buttonWidth, buttonHeight, AddressOf YesClick, _form)
        startX -= buttonWidth + buttonMargin
        btnYes.Select()
        Dim btnNo As New Button()
        InitializeButton(btnNo, "No", startX, startY, buttonWidth, buttonHeight, AddressOf NoClick, _form)
        startX -= buttonWidth + buttonMargin
        Dim btnCancel As New Button()
        InitializeButton(btnCancel, "Cancel", startX, startY, buttonWidth, buttonHeight, AddressOf CancelClick, _form)
        startX -= buttonWidth + buttonMargin
    End If

    ' Label - For Timer Countdown 
    ' If Duration has been set,start the Timer. 
    If duration > 0 Then
        isTimerRunning = True
        Dim _timerCountdownLabel As New Label
        _timerCountdownLabel.Text = "00:00:00"
        _timerCountdownLabel.Location = New Point(15, startY + 5)
        ' Add the Label To the Form 
        _form.Controls.Add(_timerCountdownLabel)
        ' Start the timer and update the countdown label
        StartTimer(_timer, duration + 50, _form, _timerCountdownLabel)
    End If
End Sub

Private Shared Sub InitializeButton(button As Button, text As String, x As Integer, y As Integer, width As Integer, height As Integer, clickHandler As EventHandler, form As Form)
    button.Text = text
    button.Width = width
    button.Height = height
    button.Location = New Point(x, y)
    button.BackColor = Color.White
    AddHandler button.Click, clickHandler
    form.Controls.Add(button)
End Sub

Private Shared Sub YesClick(sender As Object, e As EventArgs)
    _result = DialogResult.Yes
    DirectCast(sender, Button).FindForm().Close()
End Sub

Private Shared Sub NoClick(sender As Object, e As EventArgs)
    _result = DialogResult.No
    DirectCast(sender, Button).FindForm().Close()
End Sub

Private Shared Sub CancelClick(sender As Object, e As EventArgs)
    _result = DialogResult.Cancel
    DirectCast(sender, Button).FindForm().Close()
End Sub

Private Shared Sub OKClick(sender As Object, e As EventArgs)
    _result = DialogResult.OK
    DirectCast(sender, Button).FindForm().Close()
End Sub

Private Shared Sub StartTimer(_timer As Timer, duration As Integer, form As Form, countdownLabel As Label)
    _timer = New Timer()
    Dim startTime As DateTime = Now
    Dim endTime As DateTime = startTime.AddMilliseconds(duration)
    _timer.Interval = 37
    AddHandler _timer.Tick, Sub(sender As Object, e As EventArgs)
                                If Now() > endTime Then
                                    _timer.Stop()
                                    _timer.Dispose()
                                    isTimerRunning = False
                                    form.Close()
                                End If
                                Dim currentTime As DateTime = DateTime.Now
                                Dim timeRemaining As TimeSpan = endTime - currentTime
                                ' Convert TimeSpan back to DateTime to extract hours, minutes, seconds, and milliseconds
                                Dim remainingDateTime As DateTime = DateTime.Today.Add(timeRemaining)
                                ' Extract hours, minutes, seconds, and milliseconds
                                Dim hours As Integer = remainingDateTime.Hour
                                Dim minutes As Integer = remainingDateTime.Minute
                                Dim seconds As Integer = remainingDateTime.Second
                                Dim milliseconds As Integer = remainingDateTime.Millisecond
                                ' Adjust for negative timeRemaining
                                If timeRemaining < TimeSpan.Zero Then
                                    hours = 0
                                    minutes = 0
                                    seconds = 0
                                    milliseconds = 0
                                End If
                                ' Format the time as a string
                                Dim timeString As String = $"{hours:D2}:{minutes:D2}:{seconds:D2}.{milliseconds:D3}"
                                ' Update the countdown label
                                countdownLabel.Text = timeString
                            End Sub
    _timer.Start()
End Sub


Public Shared Function GetButtonClicked(ByVal passedResultCode As Integer) As String
    Select Case passedResultCode
        Case 0
            Return "none"
        Case 1
            Return "OK"
        Case 2
            Return "Cancel"
        Case 6
            Return "Yes"
        Case 7
            Return "No"
        Case Else
            Return "UNKNOWN VALUE: " & passedResultCode
    End Select
End Function

Public Shared Function ConvertPlainTextToRTF(formattedPlainText As String) As String
    Dim richTextBox As New RichTextBox()
    richTextBox.Rtf = formattedPlainText
    Dim rtf As String = richTextBox.Rtf
    richTextBox.Dispose() ' Dispose the RichTextBox after use
    Return rtf
End Function



Public Shared Function ConvertRTFToPlainText(passedRtf As String) As String
    Dim richTextBox As New RichTextBox()
    richTextBox.Rtf = passedRtf
    Dim rtfText As String = richTextBox.Rtf
    richTextBox.Dispose() ' Dispose the RichTextBox after use
    Return rtfText
End Function

下课

© www.soinside.com 2019 - 2024. All rights reserved.