Error adding control from toolbox to windows form - vb.net

i have class inherited from textbox , and when i try to add the control from the toolbox i have this error in the picture.
this is class inherited from textbox control ,using listbox control to choose from auto complete list
Public Structure Account
Dim Name As String
Dim Number As String
Public Sub New(Namee As String, Num As String)
Name = Namee
Number = Num
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Structure
Public Class AutoCompleteTextBox
Inherits TextBox
Private ACL As List(Of Account), CACL As List(Of Account)
Private CaseSensitive As Boolean
Private MinChar As Integer
Private LS As ListBox
Private OLDText As String
Private PN As Panel
Public Sub New()
MyBase.New
MinTypedCharacters = 2
CaseSesitivity = False
ACL = New List(Of Account)
LS = New ListBox
LS.Name = "SeggestionListBox"
LS.Font = Font
LS.Visible = True
PN = New Panel
PN.Visible = False
PN.Font = Font
PN.AutoSizeMode = AutoSizeMode.GrowAndShrink
PN.ClientSize = New Size(1, 1)
PN.Name = "SeggestionPanel"
PN.Padding = New Padding(0, 0, 0, 0)
PN.Margin = New Padding(0, 0, 0, 0)
PN.BackColor = Color.Transparent
PN.ForeColor = Color.Transparent
PN.PerformLayout()
If Not PN.Controls.Contains(LS) Then
PN.Controls.Add(LS)
End If
LS.Dock = DockStyle.Fill
LS.SelectionMode = SelectionMode.One
AddHandler LS.KeyDown, AddressOf LS_KeyDown
AddHandler LS.MouseClick, AddressOf LS_MouseClick
AddHandler LS.MouseDoubleClick, AddressOf LS_MouseDoubleClick
CACL = New List(Of Account)
LS.DataSource = CACL
OLDText = Text
End Sub
#Region "Properties"
Public Property AutoCompleteList As List(Of Account)
Get
Return ACL
End Get
Set(value As List(Of Account))
ACL.Clear()
ACL = value
End Set
End Property
Public Property CaseSesitivity As Boolean
Get
Return CaseSensitive
End Get
Set(value As Boolean)
CaseSensitive = value
End Set
End Property
Public Property MinTypedCharacters As Integer
Get
Return MinChar
End Get
Set(value As Integer)
MinChar = value
End Set
End Property
Public Property SelectedIndex As Integer
Get
Return LS.SelectedIndex
End Get
Set(value As Integer)
If LS.Items.Count <> 0 Then
LS.SelectedIndex = value
End If
End Set
End Property
Private ReadOnly Property ParentForm As Form
Get
Return Me.Parent.FindForm
End Get
End Property
#End Region
Public Sub HideSuggestionListBox()
If Not ParentForm Is Nothing Then
PN.Hide()
If ParentForm.Controls.Contains(PN) Then
ParentForm.Controls.Remove(PN)
End If
End If
End Sub
Private Function SelectItem() As Boolean
If LS.Items.Count > 0 AndAlso LS.SelectedIndex > -1 Then
Text = LS.SelectedItem.ToString
HideSuggestionListBox()
End If
Return True
End Function
Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
If e.KeyCode = Keys.Up Then
MoveSelection(SelectedIndex - 1)
e.Handled = True
ElseIf e.KeyCode = Keys.Down Then
MoveSelection(SelectedIndex + 1)
e.Handled = True
ElseIf e.KeyCode = Keys.PageUp Then
MoveSelection(SelectedIndex - 10)
e.Handled = True
ElseIf e.KeyCode = Keys.PageDown Then
MoveSelection(SelectedIndex + 10)
e.Handled = True
ElseIf e.KeyCode = Keys.Enter Then
SelectItem()
e.Handled = True
Else
MyBase.OnKeyDown(e)
End If
End Sub
Protected Overrides Sub OnLostFocus(e As EventArgs)
If Not PN.ContainsFocus Then
MyBase.OnLostFocus(e)
If Not CheckItem(Text) Then
Text = ""
End If
HideSuggestionListBox()
End If
End Sub
Protected Overrides Sub OnTextChanged(e As EventArgs)
If Not DesignMode Then
ShowSuggests()
End If
MyBase.OnTextChanged(e)
OLDText = Text
End Sub
Private Sub LS_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
If (e.KeyCode = Keys.Enter) Then
Me.SelectItem()
e.Handled = True
End If
End Sub
Private Sub LS_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs)
' select the current item
Me.SelectItem()
MsgBox(LS.SelectedItem.number)
End Sub
Private Sub LS_MouseDoubleClick(ByVal sender As Object, ByVal e As MouseEventArgs)
Me.SelectItem()
End Sub
Private Function CheckItem(ItemSTR As String) As Boolean
For Each STR As Account In ACL
If ItemSTR.ToLower = STR.ToString.ToLower Then
Return True
Exit Function
End If
Next
Return False
End Function
Private Sub MoveSelection(Index As Integer)
If Index <= -1 Then
SelectedIndex = 0
ElseIf Index > (LS.Items.Count - 1) Then
SelectedIndex = LS.Items.Count - 1
Else
SelectedIndex = Index
End If
End Sub
Private Sub ShowSuggests()
If Text.Length >= MinTypedCharacters Then
PN.SuspendLayout()
If Text.Length > 0 AndAlso OLDText = Text.Substring(0, Text.Length - 1) Then
UpdateCurrentAutoCompleteList()
ElseIf OLDText.Length > 0 AndAlso Text = OLDText.Substring(0, OLDText.Length - 1) Then
UpdateCurrentAutoCompleteList()
Else
UpdateCurrentAutoCompleteList()
End If
If Not CACL Is Nothing AndAlso CACL.Count > 0 Then
PN.Show()
PN.BringToFront()
Focus()
Else
HideSuggestionListBox()
End If
PN.ResumeLayout()
Else
HideSuggestionListBox()
End If
End Sub
Private Sub UpdateCurrentAutoCompleteList()
CACL.Clear()
For Each STR As Account In ACL
If CaseSesitivity = True Then
If STR.ToString.IndexOf(Text) > -1 Then
CACL.Add(STR)
End If
Else
If STR.ToString.ToLower.IndexOf(Text.ToLower) > -1 Then
CACL.Add(STR)
End If
End If
Next
If CACL.Count > 0 Then
UpdateListBoxItems()
Else
HideSuggestionListBox()
End If
End Sub
Private Sub UpdateListBoxItems()
If Not ParentForm Is Nothing Then
PN.Width = Width
'PN.Height = ParentForm.ClientSize.Height - Height - Location.Y
Dim F As Integer = ParentForm.ClientSize.Height - Height - Location.Y
Dim Ten As Integer = Font.Height * 10
Dim CUr As Integer = Font.Height * (CACL.Count + 1)
If F < CUr Then
PN.Height = F
ElseIf CUr < Ten Then
PN.Height = CUr
ElseIf Ten < F Then
PN.Height = Ten
Else
PN.Height = F
End If
'PN.Height = Font.Height * 10
PN.Location = Location + New Size(0, Height)
If Not ParentForm.Controls.Contains(PN) Then
ParentForm.Controls.Add(PN)
End If
CType(LS.BindingContext(CACL), CurrencyManager).Refresh()
End If
End Sub
End Class
firstly i used list(of string) before using the structure account .
the problem appears after using the structure
Any Idea about this error ?
**** additional picture show another problem after substitutes the structure with class and adds attribute.
***** changed the Structure to class
<Serializable> Public Class Account
Private Nam As String
Private Numbe As String
Public Sub New(Namee As String, Num As String)
Name = Namee
Number = Num
End Sub
Public Property Name As String
Get
Return Nam
End Get
Set(value As String)
Nam = value
End Set
End Property
Public Property Number As String
Get
Return Numbe
End Get
Set(value As String)
Numbe = value
End Set
End Property
Public Overrides Function ToString() As String
Return Name
End Function
End Class

Problem Resolved*
i will share the solve with you.
all the problem is coming from the line
ACL = New List(Of Account)
and the line
CACL = New List(Of Account)
because it declare new list(of account) in design time.
i solved the problem by deleting the both of line and modified the property (AutoCompleteList) to be like that.
Public WriteOnly Property AutoCompleteList As List(Of Account)
Set(value As List(Of Account))
ACL = value
CACL = New List(Of Account)
End Set
End Property
and the final code will be like that:-
the structure:
Public Structure Account
Public Name As String
Public Number As String
Public Sub New(Namee As String, Num As String)
Name = Namee
Number = Num
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Structure
the class:
Public Class AutoCompleteTextBox
Inherits TextBox
Private ACL As List(Of Account), CACL As List(Of Account)
Private CaseSensitive As Boolean
Private MinChar As Integer
Private LS As ListBox
Private OLDText As String
Private PN As Panel
Public Sub New()
MyBase.New
MinTypedCharacters = 2
CaseSesitivity = False
LS = New ListBox
LS.Name = "SeggestionListBox"
LS.Font = Font
LS.Visible = True
PN = New Panel
PN.Visible = False
PN.Font = Font
PN.AutoSizeMode = AutoSizeMode.GrowAndShrink
PN.ClientSize = New Size(1, 1)
PN.Name = "SeggestionPanel"
PN.Padding = New Padding(0, 0, 0, 0)
PN.Margin = New Padding(0, 0, 0, 0)
PN.BackColor = Color.Transparent
PN.ForeColor = Color.Transparent
PN.PerformLayout()
If Not PN.Controls.Contains(LS) Then
PN.Controls.Add(LS)
End If
LS.Dock = DockStyle.Fill
LS.SelectionMode = SelectionMode.One
AddHandler LS.KeyDown, AddressOf LS_KeyDown
AddHandler LS.MouseClick, AddressOf LS_MouseClick
AddHandler LS.MouseDoubleClick, AddressOf LS_MouseDoubleClick
LS.DataSource = CACL
OLDText = Text
End Sub
Public WriteOnly Property AutoCompleteList As List(Of Account)
Set(value As List(Of Account))
'ACL.Clear()
ACL = value
CACL = New List(Of Account)
End Set
End Property
Public Property CaseSesitivity As Boolean
Get
Return CaseSensitive
End Get
Set(value As Boolean)
CaseSensitive = value
End Set
End Property
Public Property MinTypedCharacters As Integer
Get
Return MinChar
End Get
Set(value As Integer)
MinChar = value
End Set
End Property
Public Property SelectedIndex As Integer
Get
Return LS.SelectedIndex
End Get
Set(value As Integer)
If LS.Items.Count <> 0 Then
LS.SelectedIndex = value
End If
End Set
End Property
Private ReadOnly Property ParentForm As Form
Get
Return Me.Parent.FindForm
End Get
End Property
Public Sub HideSuggestionListBox()
If Not ParentForm Is Nothing Then
PN.Hide()
If ParentForm.Controls.Contains(PN) Then
ParentForm.Controls.Remove(PN)
End If
End If
End Sub
Private Function SelectItem() As Boolean
If LS.Items.Count > 0 AndAlso LS.SelectedIndex > -1 Then
Text = LS.SelectedItem.ToString
MsgBox(LS.SelectedItem.number)
HideSuggestionListBox()
End If
Return True
End Function
Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
If e.KeyCode = Keys.Up Then
MoveSelection(SelectedIndex - 1)
e.Handled = True
ElseIf e.KeyCode = Keys.Down Then
MoveSelection(SelectedIndex + 1)
e.Handled = True
ElseIf e.KeyCode = Keys.PageUp Then
MoveSelection(SelectedIndex - 10)
e.Handled = True
ElseIf e.KeyCode = Keys.PageDown Then
MoveSelection(SelectedIndex + 10)
e.Handled = True
ElseIf e.KeyCode = Keys.Enter Then
SelectItem()
e.Handled = True
Else
MyBase.OnKeyDown(e)
End If
End Sub
Protected Overrides Sub OnLostFocus(e As EventArgs)
If Not PN.ContainsFocus Then
MyBase.OnLostFocus(e)
If Not CheckItem(Text) Then
Text = ""
End If
HideSuggestionListBox()
End If
End Sub
Protected Overrides Sub OnTextChanged(e As EventArgs)
If Not DesignMode Then
ShowSuggests()
End If
MyBase.OnTextChanged(e)
OLDText = Text
End Sub
Private Sub LS_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
If (e.KeyCode = Keys.Enter) Then
Me.SelectItem()
e.Handled = True
End If
End Sub
Private Sub LS_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs)
' select the current item
Me.SelectItem()
MsgBox(LS.SelectedItem.number)
End Sub
Private Sub LS_MouseDoubleClick(ByVal sender As Object, ByVal e As MouseEventArgs)
Me.SelectItem()
End Sub
Private Function CheckItem(ItemSTR As String) As Boolean
For Each STR As Account In ACL
If ItemSTR.ToLower = STR.ToString.ToLower Then
Return True
Exit Function
End If
Next
Return False
End Function
Private Sub MoveSelection(Index As Integer)
If Index <= -1 Then
SelectedIndex = 0
ElseIf Index > (LS.Items.Count - 1) Then
SelectedIndex = LS.Items.Count - 1
Else
SelectedIndex = Index
End If
End Sub
Private Sub ShowSuggests()
If Text.Length >= MinTypedCharacters Then
PN.SuspendLayout()
If Text.Length > 0 AndAlso OLDText = Text.Substring(0, Text.Length - 1) Then
UpdateCurrentAutoCompleteList()
ElseIf OLDText.Length > 0 AndAlso Text = OLDText.Substring(0, OLDText.Length - 1) Then
UpdateCurrentAutoCompleteList()
Else
UpdateCurrentAutoCompleteList()
End If
If Not CACL Is Nothing AndAlso CACL.Count > 0 Then
PN.Show()
PN.BringToFront()
Focus()
Else
HideSuggestionListBox()
End If
PN.ResumeLayout()
Else
HideSuggestionListBox()
End If
End Sub
Private Sub UpdateCurrentAutoCompleteList()
CACL.Clear()
For Each STR As Account In ACL
If CaseSesitivity = True Then
If STR.ToString.IndexOf(Text) > -1 Then
CACL.Add(STR)
End If
Else
If STR.ToString.ToLower.IndexOf(Text.ToLower) > -1 Then
CACL.Add(STR)
End If
End If
Next
If CACL.Count > 0 Then
UpdateListBoxItems()
Else
HideSuggestionListBox()
End If
End Sub
Sub Fill()
For Each A As Account In CACL
LS.Items.Add(A)
Next
End Sub
Private Sub UpdateListBoxItems()
If Not ParentForm Is Nothing Then
PN.Width = Width
'PN.Height = ParentForm.ClientSize.Height - Height - Location.Y
Dim F As Integer = ParentForm.ClientSize.Height - Height - Location.Y
Dim Ten As Integer = Font.Height * 10
Dim CUr As Integer = Font.Height * (CACL.Count + 1)
If F < CUr Then
PN.Height = F
ElseIf CUr < Ten Then
PN.Height = CUr
ElseIf Ten < F Then
PN.Height = Ten
Else
PN.Height = F
End If
'PN.Height = Font.Height * 10
PN.Location = Location + New Size(0, Height)
If Not ParentForm.Controls.Contains(PN) Then
ParentForm.Controls.Add(PN)
End If
Fill()
End If
End Sub
End Class
thank you all.

Related

How can i detect my datagridview when keydown?

i have a codes for selecting right cell in datagridview when datagridview cell changed or press enter key
but codes running always when i press enter key
how can i do this only i'm in datagridview ?
Private KeyHandled As Boolean
Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
If FAT_TABLO.RowCount = 0 Then Exit Function
Dim icolumn As Integer = FAT_TABLO.CurrentCell.ColumnIndex
Dim irow As Integer = FAT_TABLO.CurrentCell.RowIndex
If keyData = Keys.Enter Then
If icolumn = FAT_TABLO.Columns.Count - 1 Then
FAT_TABLO.Rows.Add()
FAT_TABLO.CurrentCell = FAT_TABLO(0, irow + 1)
Else
FAT_TABLO.CurrentCell = FAT_TABLO(icolumn + 1, irow)
End If
Return True
Else
Return MyBase.ProcessCmdKey(msg, keyData)
End If
End Function
Try this
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'add new dgv
Dim Dgv1 As New DGV
With Dgv1
.AllowUserToAddRows = False
.Columns.Add("ColA", "A")
.Columns.Add("ColB", "B")
.Columns.Add("ColC", "C")
.Rows.Add(5)
.Dock = DockStyle.Top
End With
Me.Controls.Add(Dgv1)
End Sub
End Class
Class DGV
Inherits DataGridView
Protected Overrides Function ProcessDataGridViewKey(e As KeyEventArgs) As Boolean
If e.KeyData = Keys.Enter And Me.Rows.Count > 0 Then
With Me.CurrentCell
If .ColumnIndex < Me.Columns.Count - 1 Then
'Move to next cell
Me.CurrentCell = Me.Item(NextVisCol(.ColumnIndex + 1), .RowIndex)
Return True
ElseIf .ColumnIndex = Me.Columns.Count - 1 Then
If .RowIndex = Me.Rows.Count - 1 Then
'Add new row
Me.Rows.Add()
End If
'Move to first cell in next row
If Me.Rows(.RowIndex).IsNewRow = False Then Me.CurrentCell = Me.Item(NextVisCol(0), .RowIndex + 1)
Return True
End If
End With
End If
Return MyBase.ProcessDataGridViewKey(e)
End Function
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
If keyData = Keys.Enter Then Return ProcessDataGridViewKey(New KeyEventArgs(Keys.Enter))
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
Private Function NextVisCol(Optional start As Integer = 0) As Integer
For i As Integer = start To Me.Columns.Count - 1
If Me.Columns(i).Visible Then Return i
Next
For i As Integer = 0 To Me.Columns.Count - 1
If Me.Columns(i).Visible Then Return i
Next
Throw New Exception("All columns are not visible")
End Function
End Class

DropDownCheckedListBox Issue

Was looking at making a DropDownCheckedListBox for one of my forms. I found a complete source code that was on line.
Public Class DropDownCheckedListBox
Private Const T_DisplayListSize As Integer = 6
Private Const SelectNoneText As String = "(None Selected)"
Private Const SelectAllText As String = "(All Selected)"
Private Const SelectSomeText As String = "(Some Selected...)"
Private Frm As Form
Private Shadows LostFocus As Boolean
Private CodeValue As String
Private T_MustFill As Boolean
Private Shared m_ChkItemsString As String
Public Event DropDown()
Public Shadows Event TextChanged()
Public Sub New()
InitializeComponent()
InitializeNew()
End Sub
Private Sub InitializeNew()
Dim strTemp As String = Nothing
ListSize = T_DisplayListSize
T_DroppedDown = False
T_ListText = ""
T_MustFill = False
txt.Text = strTemp
Checklisbox.Hide()
Frm = New Form
With Frm
.ShowInTaskbar = False
.FormBorderStyle = FormBorderStyle.None
.ControlBox = False
.StartPosition = FormStartPosition.Manual
.TopMost = True
.Location = Checklisbox.Location
.Width = Checklisbox.Width
.Controls.Add(Checklisbox)
End With
SetSize()
End Sub
Private dataList() As String
Public Property Items() As String()
Get
Return dataList
End Get
Set(ByVal value As String())
dataList = value
End Set
End Property
Private ListSize As Integer
Public Property DisplayListSize() As Integer
Get
Return ListSize
End Get
Set(ByVal value As Integer)
ListSize = value
SetList()
End Set
End Property
Private T_DroppedDown As Boolean
Public ReadOnly Property DroppedDown() As Boolean
Get
Return T_DroppedDown
End Get
End Property
Private T_ListText As String
Public ReadOnly Property ListText() As String
Get
Return T_ListText
End Get
End Property
Private Sub ListButtonClick()
Dim strTemp As String
strTemp = T_ListText
If T_DroppedDown Then
T_DroppedDown = False
txt.Text = GetSelectedItems()
Checklisbox.Hide()
Frm.Hide()
txt.Focus()
If Not strTemp = T_ListText Then
RaiseEvent TextChanged()
End If
ElseIf Not LostFocus Then
T_DroppedDown = True
SetSize()
Frm.Show()
Checklisbox.Show()
Checklisbox.Focus()
RaiseEvent DropDown()
End If
LostFocus = False
End Sub
Private Function GetSelectedItems() As String
Dim strLst As String
Dim blnAllSelected As Boolean = False
strLst = ""
With Checklisbox
If .Items.Count > 0 Then
If .CheckedIndices.Count = 0 Then
strLst = SelectNoneText
Else
If .CheckedIndices.Count = .Items.Count Then
strLst = SelectAllText
Else
strLst = .CheckedIndices.Count & " selected" 'SelectSomeText
End If
End If
Else
strLst = SelectNoneText
End If
End With
Return strLst
End Function
'Removed code from this area that was just click, keystrokes events.
'Also Removed resize code.
Public Event SelectedIndexChanged(ByVal sender As DropDownCheckedListBox)
Public Shared Function GetItemsNameString(ByVal tempListBox As CheckedListBox) As String
m_ChkItemsString = ""
Try
If tempListBox.CheckedItems.Count > 0 Then
Dim tempItem As Object
For Each tempItem In tempListBox.CheckedItems
m_ChkItemsString = m_ChkItemsString & "," & tempItem.ToString()
Next
End If
m_ChkItemsString = m_ChkItemsString.Trim().Substring(1, m_ChkItemsString.Length - 1)
Catch ex As Exception
End Try
Return m_ChkItemsString
End Function
Public Sub setText(ByVal chklist As CheckedListBox)
If chklist.Items.Count > 0 Then
If chklist.CheckedIndices.Count = chklist.Items.Count Then
txt.Text = SelectAllText
Exit Sub
End If
If chklist.CheckedIndices.Count > 0 Then
txt.Text = chklist.CheckedIndices.Count & " selected"
ElseIf chklist.CheckedIndices.Count = 0 Then
txt.Text = SelectNoneText
End If
Else
txt.Text = SelectNoneText
End If
End Sub
Private Sub bChkLstBox_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
If Not dataList Is Nothing Then
If dataList.GetUpperBound(0) > 0 Then
For i As Integer = 0 To dataList.GetUpperBound(0)
If Not dataList(i) Is Nothing Then
Checklisbox.Items.Add(dataList(i))
End If
Next
End If
End If
End Sub
'Removed mouse events
End Class
This code works but I discovered a problem.
When I select items 1, 2, and 3 from the list and tell it to display the items in an list box I come up with the following: 1, 1, 2, 1, 2, 3.
I am still going over the code trying to figure it out but more experience individuals advice would be helpful.
Thanks in advance, and Apologies for the long code.
Edit:
Code to send items to Listbox
Dim Litems As New List(Of String)
ListBox1.Items.Clear()
Litems.Clear()
For Each I As String In DropDownCheckedListBox1.Checklisbox.CheckedItems
Litems.Add(I)
ListBox1.Items.AddRange(Litems.ToArray)
next
Move your AddRange line to outside the loop, otherwise, you keep re-adding the contents of your list to the ListBox:
Dim Litems As New List(Of String)
ListBox1.Items.Clear()
Litems.Clear()
For Each I As String In DropDownCheckedListBox1.Checklisbox.CheckedItems
Litems.Add(I)
next
ListBox1.Items.AddRange(Litems.ToArray)

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.

vb.net: How to prevent the dropdown of a checked combobox from closing after checking or unchecking an item

I would like to prevent the dropdown list from closing when the user checks or unchecks a checkbox in a checked combobox.
I have copied some Microsoft code to created a checked combobox. As it didn't work out-of-the-box, I did some customizing.
Here's my code:
Imports System.ComponentModel
Imports System.Collections.ObjectModel
Public Class CheckedCombobox
Inherits ComboBox
Public Event ItemCheck(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs)
<Browsable(False)> _
Public Overloads ReadOnly Property Items() As ComboBox.ObjectCollection
Get
Return MyBase.Items
End Get
End Property
Private WithEvents _ItemCollection As New ObservableCollection(Of String)
Public Property ItemCollection As ObservableCollection(Of String)
Get
Return _ItemCollection
End Get
Set(value As ObservableCollection(Of String))
_ItemCollection = value
End Set
End Property
Private _ItemDictionary As New Dictionary(Of String, Boolean)
Public ReadOnly Property ItemDictionary As Dictionary(Of String, Boolean)
Get
Return _ItemDictionary
End Get
End Property
Public ReadOnly Property CheckedItemCollection As List(Of String)
Get
Return New List(Of String)(From item In ItemDictionary Where item.Value = True Select item.Key)
End Get
End Property
Public ReadOnly Property UnCheckedItemCollection As List(Of String)
Get
Return New List(Of String)(From item In ItemDictionary Where item.Value = False Select item.Key)
End Get
End Property
Public Sub setCheckState(ByVal key As String, ByVal checkstate As Boolean)
_ItemDictionary(key) = checkstate
End Sub
Public Function getCheckState(ByVal key As String)
Return (_ItemDictionary(key))
End Function
Public Sub New()
Me.DrawMode = Windows.Forms.DrawMode.OwnerDrawVariable
End Sub
Protected Overrides Sub OnCreateControl()
MyBase.OnCreateControl()
For Each item In ItemCollection
_ItemDictionary.Add(item, False)
Next
End Sub
Private Sub ItemsChanged(ByVal sender As Object, ByVal e As System.Collections.Specialized.NotifyCollectionChangedEventArgs) Handles _ItemCollection.CollectionChanged
Select Case e.Action
Case Specialized.NotifyCollectionChangedAction.Add
If e.NewStartingIndex = ItemDictionary.Count Then
_ItemDictionary.Add(e.NewItems(0), False)
MyBase.Items.Add(e.NewItems(0))
End If
Case Specialized.NotifyCollectionChangedAction.Remove
_ItemDictionary.Remove(MyBase.Items(e.OldStartingIndex))
MyBase.Items.RemoveAt(e.OldStartingIndex)
Case Specialized.NotifyCollectionChangedAction.Move
Dim _item As Object = MyBase.Items(e.OldStartingIndex)
MyBase.Items.RemoveAt(e.OldStartingIndex)
MyBase.Items.Insert(e.NewStartingIndex, _item)
Case Specialized.NotifyCollectionChangedAction.Replace
Throw New Exception("Not implemented yet!")
Case Specialized.NotifyCollectionChangedAction.Reset
Dim _checkeditems As New List(Of String)(CheckedItemCollection)
MyBase.Items.Clear()
MyBase.Items.AddRange(_ItemCollection.ToArray)
_ItemDictionary.Clear()
For Each item In _ItemCollection
_ItemDictionary.Add(item, _checkeditems.Contains(item))
Next
End Select
Me.Invalidate()
End Sub
Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)
e.DrawBackground()
Dim p As Point = e.Bounds.Location
If e.Index >= 0 Then
p.Offset(1, 1)
If getCheckState(MyBase.Items(e.Index)) Then
CheckBoxRenderer.DrawCheckBox(e.Graphics, p, VisualStyles.CheckBoxState.CheckedNormal)
Else
CheckBoxRenderer.DrawCheckBox(e.Graphics, p, VisualStyles.CheckBoxState.UncheckedNormal)
End If
p.Offset(12, 0)
e.Graphics.DrawString(MyBase.GetItemText(Me.Items(e.Index)), e.Font, New SolidBrush(e.ForeColor), p.X, p.Y)
End If
If e.State = DrawItemState.Selected Then
e.DrawFocusRectangle()
End If
MyBase.OnDrawItem(e)
End Sub
Private Sub checkedChanged(ByVal index As Integer)
Dim checked As Boolean = _ItemDictionary(MyBase.Items.Item(index))
If checked Then
_ItemDictionary(MyBase.Items.Item(index)) = False
RaiseEvent ItemCheck(Me, New ItemCheckEventArgs(index, CheckState.Unchecked, CheckState.Checked))
Else
_ItemDictionary(MyBase.Items.Item(index)) = True
RaiseEvent ItemCheck(Me, New ItemCheckEventArgs(index, CheckState.Checked, CheckState.Unchecked))
End If
Me.Invalidate()
End Sub
Private n As nWindow = Nothing
Private Const WM_CTLCOLORLISTBOX As Integer = &H134
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
MyBase.WndProc(m)
If m.Msg = WM_CTLCOLORLISTBOX Then
If n Is Nothing Then
n = New nWindow(Me)
n.AssignHandle(m.LParam)
AddHandler n.checkedChanged, AddressOf checkedChanged
End If
End If
End Sub
Private Sub CheckedCombobox_Click(sender As Object, e As System.EventArgs) Handles Me.SelectedIndexChanged
Debugger.Break()
End Sub
End Class
Public Class nWindow
Inherits NativeWindow
Private Const WM_LBUTTONDOWN As Integer = &H201
Private _combobox As CheckedCombobox
Public Event checkedChanged(ByVal index As Integer)
Public Sub New(ByVal cb As CheckedCombobox)
_combobox = cb
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_LBUTTONDOWN Then
Dim itemHeight As Integer = _combobox.ItemHeight
If New Point(m.LParam.ToInt32).Y \ itemHeight <= _combobox.Items.Count - 1 And New Point(m.LParam.ToInt32).Y \ itemHeight >= 0 Then
If New Point(m.LParam.ToInt32).X >= 1 And New Point(m.LParam.ToInt32).X <= 11 Then
RaiseEvent checkedChanged(_combobox.SelectedIndex)
End If
End If
End If
MyBase.WndProc(m)
End Sub
End Class
The code below seems to work correctly. It does what I set out to do.
(Note: I have only shown the changed routines)
Private Sub checkedChanged(ByVal index As Integer)
Dim checked As Boolean = _ItemDictionary(MyBase.Items.Item(index))
If checked Then
_ItemDictionary(MyBase.Items.Item(index)) = False
RaiseEvent ItemCheck(Me, New ItemCheckEventArgs(index, CheckState.Unchecked, CheckState.Checked))
Else
_ItemDictionary(MyBase.Items.Item(index)) = True
RaiseEvent ItemCheck(Me, New ItemCheckEventArgs(index, CheckState.Checked, CheckState.Unchecked))
End If
Me.SelectedIndex = -1
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_LBUTTONDOWN Then
Dim itemHeight As Integer = _combobox.ItemHeight
If New Point(m.LParam.ToInt32).Y \ itemHeight <= _combobox.Items.Count - 1 And New Point(m.LParam.ToInt32).Y \ itemHeight >= 0 Then
If New Point(m.LParam.ToInt32).X >= 1 And New Point(m.LParam.ToInt32).X <= 11 Then
RaiseEvent checkedChanged(_combobox.SelectedIndex)
Return
End If
End If
End If
MyBase.WndProc(m)
End Sub
I am not hundred percent sure about not calling MyBase.WndProc(), but I did not notice any side-effects yet.

Textbox validation for alphabetical and alphanumeric textbox with "."

This is what i am using but i want to include "." dot also as an input in the textbox
If Char.IsLetter(e.KeyChar) = False Then
If e.KeyChar = CChar(ChrW(Keys.Back)) or e.KeyChar = CChar(ChrW(Keys.Space)) Then
e.Handled = False
Else
e.Handled = True
End If
End If
and
If Char.IsLetterOrDigit(e.KeyChar) = False Then
If e.KeyChar = CChar(ChrW(Keys.Back)) or e.KeyChar = CChar(ChrW(Keys.Space)) Then
e.Handled = False
Else
e.Handled = True
End If
End If
To include a period in the list of valid characters, use an OrElse term to test for multiple conditions. Note that "." is a String, different to "."c which is a Char.
If Not (Char.IsLetterOrDigit(e.KeyChar) OrElse e.KeyChar = "."c) Then
If e.KeyChar = CChar(ChrW(Keys.Back)) or e.KeyChar = CChar(ChrW(Keys.Space)) Then
e.Handled = False
Else
e.Handled = True
End If
End If
You could just use ASCII code
If Asc(C$(F1)) > 122 Or Asc(C$(F1)) < 97 And Asc(C$(F1)) > 90 Or Asc(C$(F1)) < 65 And Asc(C$(F1)) > 57 Or Asc(C$(F1)) < 48 Then
Label9.Text = C$(F1) + " is an invalid Charater!"
End If
For a single character you can just do Or variable =".". ASCII works when you want a range.
The code snippet is from Numeric Base conversion program check for invalid charters in a number, which will convert any base from 2 to 36. And, with minor tweaking will work in any form of BASIC including Applesoft (tweak no end if, and all on one line, label9.text becomes a text varible) which can also be done in VB.
You can use my control:
''' <summary>
''' By Amen Ayach
''' Use RoundNumber property to set how many decimal after "."
''' example: RoundNumber = 3 so if you write 654.4444 so onlostFocus you'll see 654.444
''' </summary>
''' <remarks></remarks>
Public Class TBRound
Inherits TextBox
Dim Enterly As Boolean = True
Private _RoundNumber As Integer = 0
Public Property RoundNumber() As Integer
Get
Return _RoundNumber
End Get
Set(ByVal value As Integer)
_RoundNumber = value
End Set
End Property
Public Overrides Property Text() As String
Get
Return MyBase.Text
End Get
Set(ByVal value As String)
MyBase.Text = value
End Set
End Property
Public Function format_Number(ByVal nb As String, ByVal isDivided As Boolean, ByVal NumberAfterComma As Integer) As String
Dim str As String = ""
Try
Dim fromatString As String = ""
Dim nbs As String = "."
For i As Integer = 0 To NumberAfterComma - 1
nbs += "0"
Next
If isDivided Then
str = "#,###"
Else
str = "#"
End If
str += nbs
str = Format(Val(Decimal.Parse(nb.ToString())), str)
Catch
End Try
Return str
End Function
Private Sub TBRound_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
Dim allow As String = "0123456789." + ChrW(Keys.Back) + ChrW(Keys.Delete)
If Not allow.Contains(e.KeyChar) Then
e.Handled = True
End If
End Sub
Private Sub TBRound_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LostFocus, Me.Validated
Try
If Not Decimal.TryParse(MyBase.Text, New Decimal) Then
MyBase.Text = "0"
Else
ValDateMe()
End If
Catch
End Try
End Sub
Private Sub ValDateMe()
Try
Dim value = MyBase.Text
If Decimal.TryParse(MyBase.Text, New Decimal) Then
If MyBase.Text <> format_Number(MyBase.Text, False, RoundNumber) Then
MyBase.Text = format_Number(MyBase.Text, False, RoundNumber)
End If
Else
Enterly = False
MyBase.Text = "0"
Enterly = True
End If
Catch
End Try
End Sub
End Class
You can use the following function:
Private Function StripInput(sender As String) As String
If sender <> String.Empty Then
Dim lastChr As String = sender(sender.Length - 1)
Dim stripList As String = "`¬!""£$%^&*()_+-=}{[]}~##'':?/>.<,|\;"
If stripList.Contains(lastChr) Then
Return sender.Substring(0, sender.Length - 1)
Else
Return sender
End If
Else
Return sender
End If
End Function
and call it from the TextChanged handler of the text box with :
sender.text = StripInput(sender.text)
sender.SelectionStart = sender.Text.Length + 1
And if you want to include any character, simply remove it from the strip list.