ComboBox - MultiColumn
-
Hello, I am trying to find out if anyone has a ComboBox Control for Visual Basic .NET that will handle Multi-Columns. Also, I have seen a Drop-Down TreeView Control as well on this site...has anyone Implemented this into .NET yet? I could really use both of these ASAP!
-
Hello, I am trying to find out if anyone has a ComboBox Control for Visual Basic .NET that will handle Multi-Columns. Also, I have seen a Drop-Down TreeView Control as well on this site...has anyone Implemented this into .NET yet? I could really use both of these ASAP!
I've got multi-column data-bound ComboBox and ListBox controls, with support for column images and gridlines. They're very easy to do, so I don't think they're worth an article. Let me know if you want me to post the code here. :-D
-
Hello, I am trying to find out if anyone has a ComboBox Control for Visual Basic .NET that will handle Multi-Columns. Also, I have seen a Drop-Down TreeView Control as well on this site...has anyone Implemented this into .NET yet? I could really use both of these ASAP!
I'll split this code up over several messages. First, define the Data column object:
Imports System.ComponentModel
Imports System.Drawing<ToolboxItem(""), DesignTimeVisible(False)> _
Public Class DataColumn : Inherits ComponentProtected Shared \_StringFormatter As StringFormat Shared Sub New() \_StringFormatter = New StringFormat() With \_StringFormatter .Trimming = StringTrimming.EllipsisCharacter .FormatFlags = StringFormatFlags.NoWrap .LineAlignment = StringAlignment.Center End With End Sub
#Region "Member Vars"
Private _Image As Image
Private _DataMember As String
Private _Tag As Object
Private _Width As Integer
Private _Parent As DataColumnCollection
#End Region#Region "Constructors"
Public Sub New()
_Image = Nothing
_Width = 75
_DataMember = String.Empty
_Tag = Nothing
End Sub
Public Sub New(ByVal Image As Image)
_Image = Image
_Width = 22
_DataMember = String.Empty
_Tag = Nothing
End Sub
Public Sub New(ByVal DataMember As String)
_Image = Nothing
_Width = 75
_DataMember = DataMember
_Tag = Nothing
End Sub
Public Sub New(ByVal Width As Integer)
_Image = Nothing
_Width = Width
_DataMember = String.Empty
_Tag = Nothing
End Sub
Public Sub New(ByVal DataMember As String, ByVal Width As Integer)
_Image = Nothing
_Width = Width
_DataMember = DataMember
_Tag = Nothing
End Sub
Public Sub New(ByVal Image As Image, _
ByVal DataMember As String, _
ByVal Width As Integer)
_Image = Image
_Width = Width
_DataMember = DataMember
_Tag = Nothing
End Sub
#End RegionProtected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (\_Image Is Nothing) Then Try \_Image.Dispose() Finally \_Image = Nothing End Try End If End If MyBase.Dispose(disposing) End Sub
#Region "Properties"
<Editor("System.Windows.Forms.Design.DataMemberFieldEditor", _
"System.Drawing.Design.UITypeEditor"), _
Category("Behavior")> _
Public Overridable Property DataMember() As Strin -
Hello, I am trying to find out if anyone has a ComboBox Control for Visual Basic .NET that will handle Multi-Columns. Also, I have seen a Drop-Down TreeView Control as well on this site...has anyone Implemented this into .NET yet? I could really use both of these ASAP!
Next, define a collection of
DataColumn
s:Imports System.ComponentModel
Imports System.Collections
Imports System.Windows.FormsPublic Class DataColumnCollection : Inherits CollectionBase
Private \_Parent As Control
#Region "Constructors"
Public Sub New()
'Do Nothing
End Sub
Public Sub New(ByVal Value() As DataColumn)
AddRange(Value)
End Sub
Public Sub New(ByVal Value As DataColumnCollection)
AddRange(Value)
End Sub
#End Region#Region "Add"
Public Function Add(ByVal Value As DataColumn) As Integer
Value.Parent = Me
Return List.Add(Value)
End Function
Public Sub AddRange(ByVal Value() As DataColumn)
Dim oItem As DataColumn
For Each oItem In Value
oItem.Parent = Me
List.Add(oItem)
Next
End Sub
Public Sub AddRange(ByVal Value As DataColumnCollection)
Dim oItem As DataColumn
For Each oItem In Value
oItem.Parent = Me
List.Add(oItem)
Next
End Sub
#End RegionPublic Function Contains(ByVal Value As DataColumn) As Boolean Return List.Contains(Value) End Function Public Sub CopyTo(ByVal array() As DataColumn, ByVal index As Integer) List.CopyTo(array, index) End Sub Public Overloads Function IndexOf(ByVal Value As DataColumn) As Integer Return List.IndexOf(Value) End Function Public Sub Insert(ByVal index As Integer, ByVal Value As DataColumn) List.Insert(index, Value) End Sub Default Public Property Item(ByVal index As Integer) As DataColumn Get Return DirectCast(List.Item(index), DataColumn) End Get Set(ByVal Value As DataColumn) List.Item(index) = Value End Set End Property Protected Overrides Sub OnInsert(ByVal index As Integer, \_ ByVal Value As Object) If TypeOf Value Is DataColumn Then MyBase.OnInsert(index, Value) DirectCast(Value, DataColumn).Parent = Me Else Throw New ArgumentException() End If End Sub Protected Overrides Sub OnSet(ByVal index As Integer, \_ ByVal OldValue As Object, \_ ByVal NewValue As Object) If TypeOf NewValue Is DataColumn Then MyBase
-
Hello, I am trying to find out if anyone has a ComboBox Control for Visual Basic .NET that will handle Multi-Columns. Also, I have seen a Drop-Down TreeView Control as well on this site...has anyone Implemented this into .NET yet? I could really use both of these ASAP!
Next, a base for the ComboBox / ListBox:
Imports System.Drawing
Imports System.Windows.Forms
Imports System.ComponentModelPublic Class ComboBoxEx : Inherits ComboBox
'Or - Public Class ListBoxEx : Inherits ListBox
Protected HighlightBrush As Brush
Protected HighlightPen As Pen#Region "Constructors"
Public Sub New()
DrawMode = DrawMode.OwnerDrawFixed
ItemHeight += 1
HighlightBrush = New SolidBrush(SystemColors.Highlight)
HighlightPen = New Pen(SystemColors.HighlightText)
End Sub
#End Region#Region "Overrides"
Protected Overrides Sub OnDrawItem(ByVal e As DrawItemEventArgs)
If Not (e.Index = -1) Then
DrawListBoxItem(e)
End If
End SubProtected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then HighlightBrush.Dispose() HighlightPen.Dispose() End If MyBase.Dispose(disposing) End Sub <Browsable(False)> \_ Public Shadows Property DrawMode() As DrawMode Get Return MyBase.DrawMode End Get Set(ByVal Value As DrawMode) MyBase.DrawMode = Value End Set End Property
#End Region
#Region "Implementation"
Protected Sub DrawListBoxItem(ByVal e As DrawItemEventArgs)
'// Draw List box item
If Enabled AndAlso _
((e.State And DrawItemState.Selected) = DrawItemState.Selected) ThenDrawItemHighlight(e) Else DrawItemClearHighlight(e) End If DrawItemText(e) End Sub Protected Overridable Sub DrawItemText(ByVal e As DrawItemEventArgs) Dim currentObject As Object = Items(e.Index) Dim item As String = GetItemText(currentObject) If Not (item Is Nothing) Then Dim B As Brush If Enabled Then B = New SolidBrush(e.ForeColor) Else B = SystemBrushes.ControlDark End If e.Graphics.DrawString(item, \_ e.Font, \_ B, \_ New PointF(e.Bounds.Left + 2, e.Bounds.Top)) If Enabled Then B.Dispose() End If End Sub Protected Overridable Sub DrawItemHighlight(ByVal e As DrawItemEventArgs) Dim g As Graphics = e.Graphics Dim b As Rectangle = e.Bounds g.FillRectangle(HighlightBrush, b) g.DrawRectangle(Highli
-
Hello, I am trying to find out if anyone has a ComboBox Control for Visual Basic .NET that will handle Multi-Columns. Also, I have seen a Drop-Down TreeView Control as well on this site...has anyone Implemented this into .NET yet? I could really use both of these ASAP!
Finally, define the List/ComboBox:
Imports System.Drawing
Imports System.Windows.Forms
Imports System.ComponentModel<DesignerCategory("Component"), _
DefaultProperty("DataSource"), _
TypeConverter("System.Windows.Forms.Design.DataSourceConverter"), _
ToolboxItem(True)> _
Public Class DataComboBoxEx : Inherits ComboBoxEx
'Or - Public Class DataListBoxEx : Inherits ListBoxExPrivate \_Columns As DataColumnCollection Private \_GridLineColor As Color Private \_ShowHorizontalGridLines As Boolean Private \_ShowVerticalGridLines As Boolean Public Sub New() \_ShowVerticalGridLines = True \_ShowHorizontalGridLines = False \_Columns = New DataColumnCollection() \_Columns.Parent = Me \_GridLineColor = SystemColors.ControlDark ItemHeight = Math.Max(ItemHeight, 22) End Sub Protected Overrides Sub DrawItemText( \_ ByVal e As System.Windows.Forms.DrawItemEventArgs) Dim rItem As Rectangle = e.Bounds Dim g As Graphics = e.Graphics Dim gPen As New Pen(\_GridLineColor) Dim DS As Object If DataSource Is Nothing Then DS = Items Else DS = DataSource End If Dim rItemF As New RectangleF(rItem.X, rItem.Y, rItem.Width, rItem.Height) Dim oItem As DataColumn For Each oItem In \_Columns rItemF.Width = oItem.Width oItem.OnDraw(e, rItemF, DS, DisplayMember) If \_ShowVerticalGridLines Then g.DrawLine(gPen, rItemF.Right, rItemF.Y, rItemF.Right, rItemF.Bottom) End If rItemF.X += rItemF.Width Next If \_ShowHorizontalGridLines Then g.DrawLine(gPen, rItem.X, rItem.Bottom - 1, rItem.Right, rItem.Bottom - 1) End If gPen.Dispose() End Sub <Category("Behavior"), \_ DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> \_ Public Property Columns() As DataColumnCollection Get Return \_Columns End Get Set(ByVal Value As DataColumnCollection) \_Columns = Value \_Columns.Parent = Me End Set End Property <Category("Appearance")> \_ Public Property GridLineColor() As Color Get Return \_GridLineColor End Get Set(ByVal Value As Color) \_GridLineColor = Value End Set End Property
-
Finally, define the List/ComboBox:
Imports System.Drawing
Imports System.Windows.Forms
Imports System.ComponentModel<DesignerCategory("Component"), _
DefaultProperty("DataSource"), _
TypeConverter("System.Windows.Forms.Design.DataSourceConverter"), _
ToolboxItem(True)> _
Public Class DataComboBoxEx : Inherits ComboBoxEx
'Or - Public Class DataListBoxEx : Inherits ListBoxExPrivate \_Columns As DataColumnCollection Private \_GridLineColor As Color Private \_ShowHorizontalGridLines As Boolean Private \_ShowVerticalGridLines As Boolean Public Sub New() \_ShowVerticalGridLines = True \_ShowHorizontalGridLines = False \_Columns = New DataColumnCollection() \_Columns.Parent = Me \_GridLineColor = SystemColors.ControlDark ItemHeight = Math.Max(ItemHeight, 22) End Sub Protected Overrides Sub DrawItemText( \_ ByVal e As System.Windows.Forms.DrawItemEventArgs) Dim rItem As Rectangle = e.Bounds Dim g As Graphics = e.Graphics Dim gPen As New Pen(\_GridLineColor) Dim DS As Object If DataSource Is Nothing Then DS = Items Else DS = DataSource End If Dim rItemF As New RectangleF(rItem.X, rItem.Y, rItem.Width, rItem.Height) Dim oItem As DataColumn For Each oItem In \_Columns rItemF.Width = oItem.Width oItem.OnDraw(e, rItemF, DS, DisplayMember) If \_ShowVerticalGridLines Then g.DrawLine(gPen, rItemF.Right, rItemF.Y, rItemF.Right, rItemF.Bottom) End If rItemF.X += rItemF.Width Next If \_ShowHorizontalGridLines Then g.DrawLine(gPen, rItem.X, rItem.Bottom - 1, rItem.Right, rItem.Bottom - 1) End If gPen.Dispose() End Sub <Category("Behavior"), \_ DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> \_ Public Property Columns() As DataColumnCollection Get Return \_Columns End Get Set(ByVal Value As DataColumnCollection) \_Columns = Value \_Columns.Parent = Me End Set End Property <Category("Appearance")> \_ Public Property GridLineColor() As Color Get Return \_GridLineColor End Get Set(ByVal Value As Color) \_GridLineColor = Value End Set End Property
-
Ok, this is good. It will probably take some time for me to evaluate everything here. Will this support "unbound" data as well? Thanks a lot! :-D
It should do - if you don't specify a data source, it will use the
Items
property, which implementsIList
, so it should pick up the items from that. -
I've got multi-column data-bound ComboBox and ListBox controls, with support for column images and gridlines. They're very easy to do, so I don't think they're worth an article. Let me know if you want me to post the code here. :-D