Is there any simple way to align the ComboBox text? (Center)
If possible, I would like the items in the ComboBox to be aligned also.
Printable View
Is there any simple way to align the ComboBox text? (Center)
If possible, I would like the items in the ComboBox to be aligned also.
Here is how I would do it:-
Note that I could not find a way to center the textbox portion of the combox, only the list. Compile you program with this and this overriden combobox should appear in the toolbox of your project.vbnet Code:
Imports System.ComponentModel Public Class ComboBoxEx Inherits ComboBox Sub New() MyBase.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed End Sub 'We hide this property from the intellisense and property grid 'to prevent anyone from changing it. <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)> _ Public Shadows ReadOnly Property DrawMode() As DrawMode Get 'This property is declared merely so we can 'hide it Return MyBase.DrawMode End Get End Property Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs) Dim txt As String = MyBase.Items(e.Index).ToString Dim sf As New StringFormat e.DrawBackground() sf.Alignment = StringAlignment.Center e.Graphics.DrawString(txt, e.Font, New SolidBrush(e.ForeColor), e.Bounds, sf) e.DrawFocusRectangle() End Sub End Class
I think the edit box style (ES_CENTER) has to be set when the control is created, no clue how thats done in VB.
I was bored and came up with this, it sets the left margin of the combo's edit box so text is centered, requires API...
:pCode:
Private Sub ComboBox1_TextChanged(sender As Object, e As System.EventArgs) Handles ComboBox1.TextChanged
' center combo1 text when text changes
CenterComboText(ComboBox1)
End Sub
Private Sub CenterComboText(cbo As ComboBox)
' combo must be set to DropDown style!
If Not cbo.DropDownStyle = ComboBoxStyle.DropDown Then Return
' get handle to Edit box in combo
Dim cboEdit_hWnd As IntPtr = FindWindowEx(cbo.Handle, IntPtr.Zero, "Edit", Nothing)
' if handle found set combo edit box text left margin
If Not cboEdit_hWnd = IntPtr.Zero Then
' Determine width of string displayed
Dim textWidth As Integer
Using g As System.Drawing.Graphics = cbo.CreateGraphics()
textWidth = CInt(g.MeasureString(cbo.Text, cbo.Font).Width)
End Using
' get combo's Edit window size
Dim rct As New RECT
GetWindowRect(cboEdit_hWnd, rct)
' figure left margin so text appears centered in combo's edit box area.
Dim leftMargin As Integer = ((rct.Right - rct.Left) - textWidth) \ 2
' set left margin of combo's Edit box
SendMessage(cboEdit_hWnd, EM_SETMARGINS, EC_LEFTMARGIN, leftMargin)
End If
End Sub
Nice Edge!! Here is the revised code with Edge's contribution:-
vbnet Code:
Imports System.ComponentModel Imports System.Runtime.InteropServices Public Class ComboBoxEx Inherits ComboBox Sub New() MyBase.DrawMode = Windows.Forms.DrawMode.OwnerDrawFixed End Sub Protected Overrides Sub OnHandleCreated(ByVal e As System.EventArgs) MyBase.OnHandleCreated(e) Helpers.CenterComboText(Me) End Sub Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs) Helpers.CenterComboText(Me) MyBase.OnTextChanged(e) End Sub 'We hide this property from the intellisense and property grid 'to prevent anyone from changing it. <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never)> _ Public Shadows ReadOnly Property DrawMode() As DrawMode Get 'This property is declared merely so we can 'hide it Return MyBase.DrawMode End Get End Property Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs) Dim txt As String = MyBase.Items(e.Index).ToString Dim sf As New StringFormat e.DrawBackground() sf.Alignment = StringAlignment.Center e.Graphics.DrawString(txt, e.Font, New SolidBrush(e.ForeColor), e.Bounds, sf) e.DrawFocusRectangle() End Sub End Class Friend Class Win32API <StructLayout(LayoutKind.Sequential)> _ Public Structure RECT Public Left As Integer Public Top As Integer Public Right As Integer Public Bottom As Integer End Structure Public Const EM_SETMARGINS As Integer = &HD3 Public Const EC_LEFTMARGIN = &H1 Public Declare Function FindWindowEx Lib "User32.dll" Alias "FindWindowExA" (ByVal hWnd As IntPtr, ByVal hwndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr Public Declare Function GetWindowRect Lib "User32.dll" (ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean Public Declare Function SendMessage Lib "User32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer End Class Friend Class Helpers Public Shared Sub CenterComboText(ByVal cbo As ComboBox) ' combo must be set to DropDown style! If Not cbo.DropDownStyle = ComboBoxStyle.DropDown Then Return ' get handle to Edit box in combo Dim cboEdit_hWnd As IntPtr = Win32API.FindWindowEx(cbo.Handle, IntPtr.Zero, "Edit", Nothing) ' if handle found set combo edit box text left margin If Not cboEdit_hWnd = IntPtr.Zero Then ' Determine width of string displayed Dim textWidth As Integer Using g As System.Drawing.Graphics = cbo.CreateGraphics() textWidth = CInt(g.MeasureString(cbo.Text, cbo.Font).Width) End Using ' get combo's Edit window size Dim rct As Win32API.RECT Win32API.GetWindowRect(cboEdit_hWnd, rct) ' figure left margin so text appears centered in combo's edit box area. Dim leftMargin As Integer = ((rct.Right - rct.Left) - textWidth) \ 2 ' set left margin of combo's Edit box Win32API.SendMessage(cboEdit_hWnd, Win32API.EM_SETMARGINS, Win32API.EC_LEFTMARGIN, leftMargin) End If End Sub End Class
Awesome. Thank you.
This thread is literally over 6 1/2 years old, please don't resurrect it.