Option Explicit On Option Strict On Option Infer Off Imports System.ComponentModel _ Public Class MultilineListbox Inherits System.Windows.Forms.ListBox #Region " Variables " Private m_DrawDivider, m_MultilineEnabled As Boolean Private m_BackBrush, m_ForeBrush As SolidBrush Private m_DividerColor As Color Private m_DividerThickness As Single Private m_DividerPen As Pen Public Event MultilineEnabledChanged As EventHandler #End Region #Region " Constructor, Dispose " Public Sub New() MyBase.DrawMode = Windows.Forms.DrawMode.OwnerDrawVariable Me.DividerThickness = 1.0! Me.DividerColor = Me.ForeColor Me.DrawDivider = True Me.MultilineEnabled = True End Sub Protected Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then 'The object is being explicitly disposed so dispose its children. If m_BackBrush IsNot Nothing Then m_BackBrush.Dispose() If m_ForeBrush IsNot Nothing Then m_ForeBrush.Dispose() End If m_BackBrush = Nothing m_ForeBrush = Nothing MyBase.Dispose(disposing) End Sub #End Region #Region " Overrides: OnDrawItem, OnMeasureItem " Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs) e.DrawBackground() e.DrawFocusRectangle() If Me.Items.Count > 0I Then Try Dim isSelected As Boolean = (e.State And DrawItemState.Selected) = DrawItemState.Selected m_BackBrush = New SolidBrush(If(isSelected, SystemColors.Highlight, Me.BackColor)) m_ForeBrush = New SolidBrush(If(isSelected, SystemColors.HighlightText, Me.ForeColor)) e.Graphics.FillRectangle(m_BackBrush, e.Bounds) e.Graphics.DrawString(Me.GetItemText(Me.Items(e.Index)), Me.Font, m_ForeBrush, e.Bounds.X, e.Bounds.Y) If m_DrawDivider AndAlso e.Index < Me.Items.Count - 1I AndAlso Not isSelected Then e.Graphics.DrawLine(m_DividerPen, 0I, e.Bounds.Bottom - 1I, Me.Width, e.Bounds.Bottom - 1I) Catch : End Try End If MyBase.OnDrawItem(e) End Sub Protected Overrides Sub OnMeasureItem(ByVal e As System.Windows.Forms.MeasureItemEventArgs) If m_MultilineEnabled AndAlso Me.Items.Count > 0I Then e.ItemHeight = CInt(e.Graphics.MeasureString(Me.GetItemText(Me.Items(e.Index)), Me.Font).Height + m_DividerThickness + 0.499!) End If MyBase.OnMeasureItem(e) End Sub #End Region #Region " Shadows: IndexFromPoint " Public Shadows Function IndexFromPoint(ByVal Location As Point) As Integer Return Me.IndexFromPoint(Location.X, Location.Y) End Function Public Shadows Function IndexFromPoint(ByVal X As Integer, ByVal Y As Integer) As Integer Dim Index As Integer = -1I If Me.Items.Count > 0I Then For Counter As Integer = 0I To Me.Items.Count - 1I If Me.GetItemRectangle(Counter).Contains(X, Y) Then Index = Counter Next Counter End If Return Index End Function #End Region #Region " Properties: DrawMode, DrawGrid, DividerColor, DividerThickness " _ Public Shadows ReadOnly Property DrawMode() As Windows.Forms.DrawMode Get Return Windows.Forms.DrawMode.OwnerDrawVariable End Get End Property _ Public Property DrawDivider() As Boolean Get Return m_DrawDivider End Get Set(ByVal value As Boolean) If m_DrawDivider <> value Then m_DrawDivider = value Me.Invalidate() End If End Set End Property _ Public Property DividerColor() As Color Get Return m_DividerColor End Get Set(ByVal value As Color) If Not m_DividerColor.Equals(value) Then m_DividerColor = value If m_DividerPen IsNot Nothing Then m_DividerPen.Dispose() m_DividerPen = New Pen(m_DividerColor, m_DividerThickness) Me.Invalidate() End If End Set End Property _ Public Property DividerThickness() As Single Get Return m_DividerThickness End Get Set(ByVal value As Single) If m_DividerThickness <> value Then m_DividerThickness = value If m_DividerPen IsNot Nothing Then m_DividerPen.Dispose() m_DividerPen = New Pen(m_DividerColor, m_DividerThickness) Me.Invalidate() End If End Set End Property _ Public Property MultilineEnabled() As Boolean Get Return m_MultilineEnabled End Get Set(ByVal value As Boolean) If m_MultilineEnabled <> value Then m_MultilineEnabled = value Me.Invalidate() Call OnMultilineEnabledChanged(EventArgs.Empty) End If End Set End Property #End Region Protected Sub OnMultilineEnabledChanged(ByVal e As EventArgs) RaiseEvent MultilineEnabledChanged(Me, e) End Sub End Class