VB.NET Tab Control pause drawing while changing tabs - vb.net

I have a tab control with 5 tabs on it. Each tab has a large number of individual controls on it. (Ranging from 3 to 70 controls, all standard checkboxes, textboxes, comboboxes and radiobuttons.)
When running, the drawing seems to freeze mid-way through changing tabs. So you end up with part of the old tab's controls along with part of the new tab's controls drawn together.
I'd like to be able to stop drawing until all the controls are fully loaded and the code has finished running the "scoring" code.
I have tried using Suspend/Resume Layout on both the tab control and individual pages, but it does not seem to have any affect on drawing.
I have also tried using a custom class I found while searching for an answer, but it either doesn't pause the drawing or it causes the form to become unstable visually.
Imports System.Runtime.InteropServices
Friend Class DrawingControl
<DllImport("user32.dll")>
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal wMsg As Int32, ByVal wParam As Boolean, ByVal lParam As Int32) As Integer
End Function
Private Const WM_SETREDRAW As Integer = 11
Public Shared Sub SuspendDrawing(ByVal parent As Control)
SendMessage(parent.Handle, WM_SETREDRAW, False, 0)
End Sub
Public Shared Sub ResumeDrawing(ByVal parent As Control)
SendMessage(parent.Handle, WM_SETREDRAW, True, 0)
parent.Refresh()
End Sub
End Class
*** EDIT 11/22/2019: Adding the "Scoring" code that runs when changing tabs
Here is the sequence of events that run when changing tabs:
1) TabControl Deselecting
Private Sub tabDetails_Deselecting(sender As Object, e As TabControlCancelEventArgs) Handles tabDetails.Deselecting
tabDetails.SuspendLayout()
pgAcademic.SuspendLayout()
pgBusiness.SuspendLayout()
pgLIS.SuspendLayout()
pgPatient.SuspendLayout()
pgRegulatory.SuspendLayout()
End Sub
2) TabControl Selected - No code here - However, it's after THIS that the tabs become "combined" with the outlines of controls from each tab.
3) TabControl Index Change
Private Sub tabDetails_SelectedIndexChanged(sender As Object, e As EventArgs) Handles tabDetails.SelectedIndexChanged
Dim pg As Integer = Me.tabDetails.SelectedIndex
Select Case pg
Case 0
Me.txtPageScore.Text = score_pgPatientCare
Case 1
Me.txtPageScore.Text = score_pgBusiness
Case 2
Me.txtPageScore.Text = score_pgLIS
Case 3
Me.txtPageScore.Text = score_pgAcademic
Case 4
Me.txtPageScore.Text = score_pgRegulatory
End Select
End Sub
4) Step 3 fires this code:
Private Sub UpdateScore()
Dim intTotalScore As Integer = Vars.intNewScore 'Max Score = 708
Dim intScore As Integer = 0
If Vars.DisableEvents Then Exit Sub
Vars.DisableEvents = True
score_pgPatientCare = Scoring.UpdateScore(Me.pgPatient)
score_pgBusiness = Scoring.UpdateScore(Me.pgBusiness)
score_pgLIS = Scoring.UpdateScore(Me.pgLIS)
score_pgAcademic = Scoring.UpdateScore(Me.pgAcademic)
score_pgRegulatory = Scoring.UpdateScore(Me.pgRegulatory)
intTotalScore += (score_pgPatientCare + score_pgBusiness + score_pgLIS + score_pgAcademic + score_pgRegulatory)
Using dbTPT As New BGL_ApplicationsEntities
'** Use this area if needing to calculate more than YES/NO
'**********************
'*** Patient Care ***
'**********************
If chkPatientCare_IRB.Checked Then
If Not txtPatientCare_IRB.Text.Trim = "" Then
Dim propertyName = "PatientCare_IRB_Approved"
intScore = CType(weightSettings.Items.Item(propertyName), Integer)
score_pgPatientCare += intScore
intTotalScore += intScore
End If
End If
'**********************
'*** Business ***
'**********************
If chkBusiness_Replace.Checked Then
If chkBusiness_Outdated.Checked Or
chkBusiness_Inferior.Checked Or
chkBusiness_Savings.Checked Then
intScore = 0
Dim propertyName = "Business_Replace_Just"
intScore = CType(weightSettings.Items.Item(propertyName), Integer)
score_pgBusiness += intScore
intTotalScore += intScore
End If
End If
End Using
ssLabel.Text = "Total Score: " + intTotalScore.ToString
custProgBar.Value = intTotalScore
Dim pg As Integer = Me.tabDetails.SelectedIndex
Select Case pg
Case 0
Me.txtPageScore.Text = score_pgPatientCare
Case 1
Me.txtPageScore.Text = score_pgBusiness
Case 2
Me.txtPageScore.Text = score_pgLIS
Case 3
Me.txtPageScore.Text = score_pgAcademic
Case 4
Me.txtPageScore.Text = score_pgRegulatory
End Select
Vars.DisableEvents = False
End Sub
5) The above code fires this code for each tab:
Module Scoring
Public Function UpdateScore(ByVal tab As TabPage) As Integer
Dim intPgScore As Integer = 0
Dim intScore As Integer = 0
Dim intMult As Integer = 0
Dim arrPropName() As String
Dim strPropName As String
Dim strYesNo As String = Nothing
'If Vars.DisableEvents Then Return 0
'Vars.DisableEvents = True
Using dbTPT As New BGL_ApplicationsEntities
If tab.Name = "pgPatient" Then
For Each pan In tab.ChildControls(Of Panel)
If pan.Name.ToString.Substring(0, 6) = "chkgrp" Then
Dim cuScores() As Integer = {0, 0, 0, 0, 0}
Dim i As Integer = 0
For Each chk As CheckBox In pan.ChildControls(Of CheckBox)
If chk.Checked Then
arrPropName = Split(chk.Name.Replace("chk", "").Replace("CU", "PatientCare"), "_")
strPropName = arrPropName(0) + "_" + arrPropName(1)
Dim w = dbTPT.tbl_Weights.FirstOrDefault(Function(n) n.Weight_Name = strPropName)
If w IsNot Nothing Then
intScore = CType(frmNewProject.weightSettings.Items.Item(arrPropName(0) + "_" + arrPropName(1)), Integer)
intMult = CType(frmNewProject.weightSettings.Items.Item(arrPropName(0) + "_" + arrPropName(2)), Integer)
cuScores(i) = intScore * intMult
End If
Else
cuScores(i) = 0
End If
i += 1
Next
For Each txt In pan.ChildControls(Of TextBox)
txt.Text = cuScores.Max.ToString
Next
intPgScore += cuScores.Max
End If
Next
End If
For Each chk As CheckBox In tab.ChildControls(Of CheckBox)
intScore = 0
arrPropName = Split(chk.Name.Replace("chk", ""), "_")
If Not arrPropName(0) = "CU" Then
If chk.Checked Then strYesNo = "_Yes" Else strYesNo = "_No"
strPropName = arrPropName(0) + "_" + arrPropName(1) + strYesNo
Dim w = dbTPT.tbl_Weights.FirstOrDefault(Function(n) n.Weight_Name = strPropName)
If w IsNot Nothing Then
intScore = CType(frmNewProject.weightSettings.Items.Item(strPropName), Integer)
End If
End If
intPgScore += intScore
Next
For Each rad As RadioButton In tab.ChildControls(Of RadioButton)
intScore = 0
arrPropName = Split(rad.Name.Replace("rad", ""), "_", 2)
strPropName = arrPropName(0) + "_" + arrPropName(1)
If rad.Checked Then
Dim w = dbTPT.tbl_Weights.FirstOrDefault(Function(n) n.Weight_Name = strPropName)
If w IsNot Nothing Then
intScore = CType(frmNewProject.weightSettings.Items.Item(arrPropName(0) + "_" + arrPropName(1)), Integer)
End If
End If
intPgScore += intScore
Next
For Each cbox As ComboBox In tab.ChildControls(Of ComboBox)
intScore = 0
If cbox.SelectedIndex > -1 Then
If cbox.SelectedIndex = 0 Then
intScore = 0
Else
strPropName = cbox.Name.Replace("cbox", "") + cbox.SelectedValue
Dim w = dbTPT.tbl_Weights.FirstOrDefault(Function(n) n.Weight_Name = strPropName)
If w IsNot Nothing Then
intScore = CType(frmNewProject.weightSettings.Items.Item(strPropName), Integer)
End If
End If
intPgScore += intScore
End If
Next
End Using
Return intPgScore
End Function
End Module
6) Selected tab is painted
Private Sub Paint_Tab(sender As Object, e As PaintEventArgs) Handles _
pgAcademic.Paint, pgBusiness.Paint, pgLIS.Paint, pgPatient.Paint, pgRegulatory.Paint
tabDetails.ResumeLayout()
pgAcademic.ResumeLayout()
pgBusiness.ResumeLayout()
pgLIS.ResumeLayout()
pgPatient.ResumeLayout()
pgRegulatory.ResumeLayout()
End Sub

Related

Find And Format String in RichTextBox Vb.NET

I am working with Vb.NET and the requirement was to find the string n RTF control and make it , bold,italic or whatever color,I have done my efforts to find the string but yesterday I found it not working as per my requirement.
At bottom I will write the full code with test data.
I have a simple form and two control on it, One is CombBox to Select Different Test Cases and One RichTextBox for Displaying the Text.
'Class Declarations
Private FormattingApplied As Boolean = False
Private SelectedBold As Boolean = False
Private SearchText As String = String.Empty
Private SelectedItalic As Boolean = False
Private SelectedUnderLine As Boolean = False
' On Form Load
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
cmbList.Items.Add("Apple Pina Apple")
cmbList.Items.Add("Apple Delicious Pineapple")
cmbList.Items.Add("Apple Milk Shake Apa")
cmbList.Items.Add("Apple Strawberry ")
FormattingApplied = True
SelectedBold = True
cmbList.SelectedIndex = 0
End Sub
Function UppercaseFirstLetter(ByVal val As String) As String
' Test for nothing or empty.
If String.IsNullOrEmpty(val) Then
Return val
End If
Dim array() As Char = val.ToCharArray
array(0) = Char.ToUpper(array(0))
Return New String(array)
End Function
Private Sub ApplyFormatting(ByVal SearchText As String)
Dim TrimmedString As String = String.Empty
Dim ISTrimmed As Boolean = False
If FormattingApplied Then
Dim count As New List(Of Integer)()
If rtfText.Text.Length >= 53 Then
rtfText.Text = rtfText.Text.Substring(0, 50) + "..."
End If
For i As Integer = 0 To rtfText.Text.Length - 1
If rtfText.Text.IndexOf(SearchText, i) <> -1 Then
count.Add(rtfText.Text.IndexOf(SearchText, i))
ElseIf rtfText.Text.IndexOf(UppercaseFirstLetter(SearchText), i) <> -1 Then
count.Add(rtfText.Text.IndexOf(UppercaseFirstLetter(SearchText), i))
End If
Next
Try
For i As Integer = 0 To count.Count - 1
rtfText.[Select](count(i), SearchText.Length)
If SelectedBold Then
rtfText.SelectionFont = New Font(rtfText.Font, FontStyle.Bold)
ElseIf SelectedItalic Then
rtfText.SelectionFont = New Font(rtfText.Font, FontStyle.Italic)
ElseIf SelectedUnderLine Then
rtfText.SelectionFont = New Font(rtfText.Font, FontStyle.Underline)
'ElseIf SelectedBold AndAlso SelectedItalic AndAlso SelectedUnderLine Then
' rtfText.SelectionFont = New Font(rtfText.Font, FontStyle.Underline)
End If
count.RemoveAt(i)
Next
'For i As Integer = 0 To count.Count - 1
' rtfText.[Select](count(i), SearchText.Length)
' If SelectedBold Then
' rtfText.SelectionFont = New Font(rtfText.Font, FontStyle.Bold)
' ElseIf SelectedItalic Then
' rtfText.SelectionFont = New Font(rtfText.Font, FontStyle.Italic)
' ElseIf SelectedUnderLine Then
' rtfText.SelectionFont = New Font(rtfText.Font, FontStyle.Underline)
' End If
' count.RemoveAt(i)
'Next
Catch
count.Reverse()
End Try
rtfText.[Select](rtfText.Text.Length, 0)
rtfText.SelectionFont = New Font(rtfText.Font, FontStyle.Regular)
End If
End Sub
Private Sub cmbList_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbList.SelectedIndexChanged
rtfText.Text = cmbList.SelectedItem.ToString()
rtfText.[Select](0, rtfText.Text.Length)
rtfText.SelectionFont = New Font(rtfText.Font, FontStyle.Regular)
If cmbList.SelectedIndex > -1 Then
ApplyFormatting("apple")
End If
End Sub
Here is the output:
Use this method
Private Sub formatString(ByVal SearchText As String)
Dim position As Integer = 0
Dim rtfString As String = LCase(rtfText.Text)
Dim cnt As Integer = 0
Dim isStop As Boolean = False
While Not isStop
Dim i As Integer = rtfString.IndexOf(SearchText, cnt)
If i < 0 Then
isStop = True
Else
rtfText.Select(i, SearchText.Length)
rtfText.SelectionFont = New Font(rtfText.Font, FontStyle.Bold)
cnt = i + 1
End If
End While
rtfText.Select(position, 0)
End Sub
in the cmbList_SelectedIndexChanged
If cmbList.SelectedIndex > -1 Then
'ApplyFormatting("apple")
formatString("apple")
End If

VB.NET Make label show upon mouse enter

I have a code that makes small boxes at the side of the screen that when the mouse hovers over it, it grows and displays information in the label. How could I do this? Currently, the form does not register the label.
This is the button to make the form and the label.
Private Sub MakeForm()
Dim number As Integer = 1
Dim xaxis As Integer = 0
Dim yaxis As Integer = 0
Dim formlist As New List(Of Form)
Dim index As Integer = 0
For Each x In lstDate.Items
Dim frm As New Form
frm.Name = "frm" & number
frm.Text = "New Form"
frm.StartPosition = FormStartPosition.Manual
frm.FormBorderStyle = Windows.Forms.FormBorderStyle.None
frm.TopMost = True
frm.Opacity = 0.4
Dim lbl As New Label
lbl.Text = x & vbNewLine & lstAssignments.Items.Item(index) & vbNewLine & lstAN.Items.Item(index)
lbl.ForeColor = Color.White
frm.Controls.Add(lbl)
lbl.Hide()
AddHandler frm.MouseEnter, AddressOf frm_MouseEnter
AddHandler frm.MouseLeave, AddressOf frm_MouseLeave
If DateDiff(DateInterval.Day, Now(), x) <= 1 Then
frm.BackColor = Color.Red
Else
frm.BackColor = Color.Black
End If
frm.AllowTransparency = True
formlist.Add(frm)
frm.Show()
number += 1
frm.Size = New Size(20, 50)
frm.Location = New Point(My.Computer.Screen.Bounds.Size.Width - frm.Width, yaxis)
yaxis += frm.Height + 10
index += 1
Next
End Sub
This is the code for mouse entry
Private Sub frm_MouseEnter(ByVal sender As System.Object, ByVal e As EventArgs)
Dim frm1 As Form = DirectCast(sender, Form)
Dim lbl As Label = New Label
lbl.Show()
frm1.Opacity = 1
frm1.BringToFront()
frm1.Size = New Size(200, 100)
Dim test As Integer = 1
Dim counter As Integer = 0
Dim yaxis As Integer = 0
Dim fin As Boolean = False
Do Until fin = True
If frm1.Name = "frm" & test Then
yaxis = counter
fin = True
Else
counter += 60
test += 1
End If
Loop
frm1.Location = New Point(My.Computer.Screen.Bounds.Size.Width - frm1.Width, yaxis)
End Sub
This is the code for mouse leave
Private Sub frm_MouseLeave(ByVal sender As System.Object, ByVal e As EventArgs)
Dim frm1 As Form = DirectCast(sender, Form)
frm1.Opacity = 0.4
frm1.BringToFront()
frm1.Size = New Size(20, 50)
Dim test As Integer = 1
Dim counter As Integer = 0
Dim yaxis As Integer = 0
Dim fin As Boolean = False
Do Until fin = True
If frm1.Name = "frm" & test Then
yaxis = counter
fin = True
Else
counter += 10 + frm1.Height
test += 1
End If
Loop
frm1.Location = New Point(My.Computer.Screen.Bounds.Size.Width - frm1.Width, yaxis)
End Sub
Thanks!

I can't find the cause of this Stack Overflow Exception

Ever since I added the CheckForCollision_Enemy method, I've been getting a stack overflow exception every time I run my code.
Here is the CheckForCollision_Enemy method, in the Main class.
Public Sub CheckForCollision_Enemy()
Dim ship1 As New Enemy(Nothing, Nothing)
Dim ship2 As New Enemy(Nothing, Nothing)
Debug.Print("")
Dim ships = {acc_e, bs_e, sb_e, ds_e, pb_e}
For i As Integer = 0 To ships.Length - 1
ship1 = ships(i)
For j As Integer = 0 To ships.Length - 1
ship2 = ships(j)
If ship1.name <> ship2.name Then
For l As Integer = 0 To ship1.length - 1
For t As Integer = 0 To ship2.length - 1
If ship1.space_filled(l, 0) = ship2.space_filled(t, 0) And ship1.space_filled(l, 1) = ship2.space_filled(t, 1) Then
Debug.Print("Collision at {" & ship1.space_filled(l, 0) & ", " & ship1.space_filled(l, 1) & "} " & ship1.name & " VS " & ship2.name)
End If
Next
Next
End If
Next
Next
End Sub
Here is the Enemy class. This is the class where the error is shown. I marked exactly where as a comment.
Shared gen As New Random()
Dim x As Integer = 0
Dim y As Integer = 0
Public Sub New(ByVal namep As String, ByVal lengthp As Integer)
name = namep
length = lengthp
ReDim _start_point(2)
ReDim _space_filled(length, 2)
GenerateDirection()
If direction = "horizontal" Then
x = gen.Next(0, 11 - length)
y = gen.Next(0, 10)
ElseIf direction = "vertical" Then
x = gen.Next(0, 10)
y = gen.Next(0, 11 - length)
End If
GenerateStartPoint()
ExtendStartPoint()
DefineFilled()
ColorFilled()
Main.CheckForCollision_Enemy() 'If this is taken out, it will work fine.
End Sub
Public Sub GenerateStartPoint()
start_point = {x, y}
End Sub
Public Sub GenerateDirection()
If gen.Next(0, 2) = 0 Then
direction = "horizontal"
Else
direction = "vertical"
End If
End Sub
Public Sub ExtendStartPoint()
If direction = "horizontal" Then
For i As Integer = 0 To length - 1
space_filled(i, 0) = start_point(0) + i
space_filled(i, 1) = start_point(1)
Next
ElseIf direction = "vertical" Then
For i As Integer = 0 To length - 1
space_filled(i, 0) = start_point(0)
space_filled(i, 1) = start_point(1) + i
Next
End If
End Sub
Public Sub DefineFilled()
For i As Integer = 0 To length - 1
x = space_filled(i, 0)
y = space_filled(i, 1)
Try
generate = False
Main.TrackerBoard.box_list(x, y).full = True
Catch
End Try
Next
End Sub
Private Sub ColorFilled()
For y As Integer = 0 To 9
For x As Integer = 0 To 9
'Debug.Print(Main.PlayerBoard.box_list(x, y).full)
If Main.TrackerBoard.box_list(x, y).full = True Then 'New error: "InvalidOperationException"
Main.TrackerBoard.box_list(x, y).image.BackColor = System.Drawing.Color.Red
Else
Main.TrackerBoard.box_list(x, y).image.BackColor = System.Drawing.Color.Silver 'Most often, the error appears here.
End If
Next
Next
End Sub
Here is the ship class. I've taken out most of the methods to save space; if you want to see anything, I'll add it in for you.
Public Class Ship
Dim _name As String
Public Property name() As String ...
Dim WithEvents _image As PictureBox
Public Property image() As PictureBox ...
Dim _length As Integer
Public Property length() As Integer ...
Dim _direction As String
Public Property direction() As String ...
Dim _selected As Boolean
Public Property selected() As Boolean ...
Dim _placed As Boolean
Public Property placed() As Boolean ...
Dim _location() As Integer = {0, 0}
Public Property location() As Integer() ...
Dim _has_moved As Boolean
Public Property has_moved() As Boolean ...
Dim _space_filled(,) As Integer
Public Property space_filled() As Integer(,) ...
Public rect As System.Drawing.Rectangle
Dim mouse_up As Boolean = False
Dim tile_size As Integer = 25
Public Sub New(ByVal namep As String, ByVal imagep As PictureBox, ByVal lengthp As Integer, ByVal directionp As String, ByVal selectedp As Boolean, ByVal placedp As Boolean)
name = namep
image = imagep
length = lengthp
direction = directionp
selected = selectedp
placed = placedp
location(0) = 0
location(1) = 0
ReDim space_filled(length, 2)
rect = New System.Drawing.Rectangle(location(0), location(1), length * tile_size, 1 * tile_size)
End Sub
Private Sub Ship_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles _image.MouseMove ...
Private Sub Ships_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles _image.MouseClick ...
Private Sub Ship_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles _image.MouseUp ...
Public Sub Update() ...
Public Sub SnapToBox() ...
Private Sub DefineSpaceFilled() ...
Private Sub ColorFilled() ...
End Class
Your CheckForCollision_Enemy calls New Enemy, and New Enemy calls CheckForCollision_Enemy. You are recursing until the stack overflows.

Show a MessageBox centered in form

There is a way to center a MessageBox without subclassing or hooking?
I'm looking for VB.NET code.
The solution for VB.NET:
This code is taken and translated from an asnwer of #Hans Passant: Winforms-How can I make MessageBox appear centered on MainForm?
Centered_MessageBox.vb
Imports System.Text
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Class Centered_MessageBox
Implements IDisposable
Private mTries As Integer = 0
Private mOwner As Form
Public Sub New(owner As Form)
mOwner = owner
owner.BeginInvoke(New MethodInvoker(AddressOf findDialog))
End Sub
Private Sub findDialog()
' Enumerate windows to find the message box
If mTries < 0 Then
Return
End If
Dim callback As New EnumThreadWndProc(AddressOf checkWindow)
If EnumThreadWindows(GetCurrentThreadId(), callback, IntPtr.Zero) Then
If System.Threading.Interlocked.Increment(mTries) < 10 Then
mOwner.BeginInvoke(New MethodInvoker(AddressOf findDialog))
End If
End If
End Sub
Private Function checkWindow(hWnd As IntPtr, lp As IntPtr) As Boolean
' Checks if <hWnd> is a dialog
Dim sb As New StringBuilder(260)
GetClassName(hWnd, sb, sb.Capacity)
If sb.ToString() <> "#32770" Then
Return True
End If
' Got it
Dim frmRect As New Rectangle(mOwner.Location, mOwner.Size)
Dim dlgRect As RECT
GetWindowRect(hWnd, dlgRect)
MoveWindow(hWnd, frmRect.Left + (frmRect.Width - dlgRect.Right + dlgRect.Left) \ 2, frmRect.Top + (frmRect.Height - dlgRect.Bottom + dlgRect.Top) \ 2, dlgRect.Right - dlgRect.Left, dlgRect.Bottom - dlgRect.Top, True)
Return False
End Function
Public Sub Dispose() Implements IDisposable.Dispose
mTries = -1
End Sub
' P/Invoke declarations
Private Delegate Function EnumThreadWndProc(hWnd As IntPtr, lp As IntPtr) As Boolean
<DllImport("user32.dll")> _
Private Shared Function EnumThreadWindows(tid As Integer, callback As EnumThreadWndProc, lp As IntPtr) As Boolean
End Function
<DllImport("kernel32.dll")> _
Private Shared Function GetCurrentThreadId() As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function GetClassName(hWnd As IntPtr, buffer As StringBuilder, buflen As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindowRect(hWnd As IntPtr, ByRef rc As RECT) As Boolean
End Function
<DllImport("user32.dll")> _
Private Shared Function MoveWindow(hWnd As IntPtr, x As Integer, y As Integer, w As Integer, h As Integer, repaint As Boolean) As Boolean
End Function
Private Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
End Structure
End Class
Usage:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using New Centered_MessageBox(Me)
MessageBox.Show("Test Text", "Test Title", MessageBoxButtons.OK)
End Using
End Sub
Sadly there is no way to centre a MessageBox to a parent. It centres on the screen by default, and cannot be changed.
Create Your Own - Easy Create a form (get rid of controlbox in properties set false)
Place Textbox (called TextBox_Prompt) and set it to multiline in properties
Add 3 Buttons (wide/height enough to hold "CANCEL" comfortably) below the text box
add below code to your form (I used the | character to denote a newline):
Public Class frmMsgBox
Private mName As String = "Message Box" ' default name for form
Private mLocation As Point = New Point(400, 400) ' default location in case user does set
Private mStyle As MsgBoxStyle
Private mPrompt As String
Private mResult As MsgBoxResult
Private b1Result As MsgBoxResult
Private b2Result As MsgBoxResult
Private b3Result As MsgBoxResult
Public WriteOnly Property Style As MsgBoxStyle
Set(value As MsgBoxStyle)
mStyle = value
End Set
End Property
Public WriteOnly Property Prompt As String
Set(value As String)
mPrompt = value
End Set
End Property
Public ReadOnly Property Result As MsgBoxResult
Get
Return mResult
End Get
End Property
Public WriteOnly Property pLocation As Point
Set(value As Point)
mLocation = value
End Set
End Property
Public WriteOnly Property sName As String
Set(value As String)
mName = value
End Set
End Property
Private Sub frmMsgBox_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim strPrompt() As String = mPrompt.Split("|") ' use | for splitting lines
Dim sWidth As Integer = 0
Dim sHeight As String = ""
Me.Text = mName
For Each sLine As String In strPrompt ' get maximum width and height necessary for Prompt TextBox
sWidth = Math.Max(sWidth, TextRenderer.MeasureText(sLine, TextBox_Prompt.Font).Width)
sHeight += "#" + vbCrLf ' TextRenderer.MeasureText("#", TextBox_Prompt.Font).Height
TextBox_Prompt.Text += sLine + vbCrLf
Next
TextBox_Prompt.Width = Math.Min(800, sWidth + 5) ' set max width arbitrarily at 800
TextBox_Prompt.Height = Math.Min(600, TextRenderer.MeasureText(sHeight, TextBox_Prompt.Font).Height) ' set max height to 600 pixels
Me.Width = Math.Max(Me.Width, TextBox_Prompt.Width + Me.Width - Me.ClientRectangle.Width + 20)
TextBox_Prompt.Left = Math.Max(10, (Me.ClientRectangle.Width - TextBox_Prompt.Width) \ 2)
Button1.Top = TextBox_Prompt.Top + TextBox_Prompt.Height + 20
Button2.Top = Button1.Top : Button3.Top = Button1.Top
Me.Height = Me.Height - Me.ClientRectangle.Height + 2 * TextBox_Prompt.Top + TextBox_Prompt.Height + Button1.Height + 20
Dim Space2 As Integer = (Me.ClientRectangle.Width - 2 * Button1.Width) / 3
Dim Space3 As Integer = (Me.ClientRectangle.Width - 3 * Button1.Width) / 4
Select Case mStyle
Case MsgBoxStyle.AbortRetryIgnore
Button1.Text = "Abort" : Button2.Text = "Retry" : Button3.Text = "Ignore"
Button1.Left = Space3
Button2.Left = 2 * Space3 + Button1.Width
Button3.Left = 3 * Space3 + 2 * Button1.Width
b1Result = MsgBoxResult.Abort : b2Result = MsgBoxResult.Retry : b3Result = MsgBoxResult.Ignore
Case MsgBoxStyle.YesNoCancel
Button1.Text = "Yes" : Button2.Text = "No" : Button3.Text = "Cancel"
Button1.Left = Space3
Button2.Left = 2 * Space3 + Button1.Width
Button3.Left = 3 * Space3 + 2 * Button1.Width
b1Result = MsgBoxResult.Yes : b2Result = MsgBoxResult.No : b3Result = MsgBoxResult.Cancel
Case MsgBoxStyle.YesNo
Button1.Text = "Yes" : Button2.Text = "No" : Button3.Visible = False
Button1.Left = Space2
Button2.Left = 2 * Space2 + Button1.Width
b1Result = MsgBoxResult.Yes : b2Result = MsgBoxResult.No
Case MsgBoxStyle.OkCancel
Button1.Text = "Ok" : Button2.Text = "Cancel" : Button3.Visible = False
Button1.Left = Space2
Button2.Left = 2 * Space2 + Button1.Width
b1Result = MsgBoxResult.Ok : b2Result = MsgBoxResult.Cancel
Case MsgBoxStyle.RetryCancel
Button1.Text = "Retry" : Button2.Text = "Cancel" : Button3.Visible = False
Button1.Left = Space2
Button2.Left = 2 * Space2 + Button1.Width
b1Result = MsgBoxResult.Retry : b2Result = MsgBoxResult.Cancel
Case MsgBoxStyle.OkOnly
Button1.Visible = False : Button2.Text = "Ok" : Button3.Visible = False
Button1.Left -= Space2 : Button2.Width += 2 * Space2
b2Result = MsgBoxResult.Ok
End Select
Me.Location = New Point(mLocation.X - Me.Width \ 2, mLocation.Y - Me.Height \ 2)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
mResult = b1Result
Me.Close()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
mResult = b2Result
Me.Close()
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
mResult = b3Result
Me.Close()
End Sub
End Class
to use your program you can do the following
Dim ans as MsgBoxResult
Using f As New frmMsgBox With {
.sName = "form tile goes here ",
.Style = MsgBoxStyle.YesNoCancel, ' or whatever style
.Prompt = "Your prompt|2nd line||4th line",
.pLocation = New Point(Me.Left + Me.Width \ 2, Me.Top + Me.Height \ 2)
} ' this location will center MsgBox on form
f.ShowDialog()
ans = f.Result
End Using
If ans = MsgBoxResult.Yes Then
'do whatever
ElseIf ans = MsgBoxResult.No then
'do not whatever
Else ' was cancel
' do cancel
End If
I use this form all the time
You can also add a picture property/box to your form as well as other stuff.
Georg
This is my own message box use C# winform, In addition to the realization of the parent form in the center, can customize the button text and icon. You can convert it to VB code yourself.

How to have Marquee kind of text in vb.net?

Is there any way to make the text in a Windows Form to scroll like the text in a marquee tag in HTML?
You can use a timer and a couple of variables to help you do so. Something like this can be done...
'Class-level variables.
Private m_intMarqueeCounter As Integer = 1
Private m_bolMarqueeIncrementUp As Boolean = True
Private Sub YourMarqueeTimer_Tick()
'You can decide what number is best for your app.
If m_intMarqueeCounter = 10 Then
m_bolMarqueeIncrementUp = False
End If
If m_intMarqueeCounter = 0 Then
m_bolMarqueeIncrementUp = True
End If
Dim intX As Integer
For intX = 0 to m_intMarqueeCounter
frmYourForm.Text = " " & "Your Title"
Next
If m_bolMarqueeIncrementUp Then
m_intMarqueeCounter += 1
Else
m_intMarqueeCounter -= 1
End If
End Sub
Const marqueeText As String = "The quick brown fox... "
Dim sb As New System.Text.StringBuilder
Dim direction As Boolean = False 'true = left to right, false = right to left
Private Sub Timer1_Tick(sender As System.Object, _
e As System.EventArgs) Handles Timer1.Tick
If sb.Length = 0 Then sb.Append(marqueeText)
If direction Then
sb.Insert(0, sb(sb.Length - 1))
sb.Remove(sb.Length - 1, 1)
Else
sb.Append(sb(0))
sb.Remove(0, 1)
End If
Me.Text = sb.ToString
End Sub