ImageComboBox

16/04/2009 - 11:04 von Werner Kistner | Report spam
Hallo, bei VB6 gab es eine ImageComboBox die bei NET leider unter die Ràder
kam. Gibt es eine Möglichkeit dies bei NET zu verwirklichen. Für
DropDownStyle --> DropDown gibt es eine Möglichkeit. Ich benötige jedoch
DropDownStyle --> DropDownList um keine Änderung der Eintràge zuzulassen.
Besten Dank
Werner
 

Lesen sie die antworten

#1 Thorsten Doerfler
16/04/2009 - 12:05 | Warnen spam
Werner Kistner schrieb:
Hallo, bei VB6 gab es eine ImageComboBox die bei NET leider unter die Ràder
kam. Gibt es eine Möglichkeit dies bei NET zu verwirklichen.



Ja. Ein Beispiel, das sich nah an dem von VB6 bekannten ImageCombo
Control orientiert. Enthàlt paar Dinge, die ich projektspezifisch so
haben wollte und verzichtet auf eine typisierte ImageComboItem
Auflistung, sowie Designer Unterstützung:

' ImageCombo.vb
Imports System.ComponentModel

Public Class ImageCombo
Inherits System.Windows.Forms.ComboBox

Private m_ImageList As System.Windows.Forms.ImageList
Private m_DropDownHeight As Integer
Private m_Font As Font

Public Shadows Property Font() As System.Drawing.Font
Get
Return m_Font
End Get
Set(ByVal value As System.Drawing.Font)
m_Font = value

' Set controls font to adjust combobox height:
If m_Font.Size > 9.25 Then
MyBase.Font = New Font(MyBase.Font.Name, m_Font.Size)
Else
MyBase.Font = New Font(MyBase.Font.Name, 9.25)
End If
End Set
End Property

Public Property ImageList() As System.Windows.Forms.ImageList
Get
Return m_ImageList
End Get

Set(ByVal value As System.Windows.Forms.ImageList)
m_ImageList = value
End Set
End Property

Public Sub New()
MyBase.New()

MyBase.DrawMode = Windows.Forms.DrawMode.OwnerDrawVariable
Me.DropDownStyle = ComboBoxStyle.DropDownList
MyBase.DisplayMember = "Text"
m_Font = DirectCast(MyBase.Font.Clone, Font)

' Set controls font to adjust combobox height:
MyBase.Font = New Font(Me.Font.Name, 9.25)
End Sub

Protected Overrides Sub OnDrawItem( _
ByVal e As System.Windows.Forms.DrawItemEventArgs)
Dim lImgSize As Drawing.Size
Dim lPadding As Integer
Dim lIndentationOffset As Integer
Dim lImageIndentation As Integer
Dim lForeColor As Color
Dim lImage As Image = Nothing
Dim lFont As Font
Dim lTextRect As Rectangle
Dim lItem As ImageComboItem
Dim lTextFmt As StringFormat

' Obtain item to draw
If e.Index = -1 Then
If TypeOf Me.SelectedItem Is ImageComboItem Then
lItem = DirectCast(Me.SelectedItem, ImageComboItem)

Else
lItem = New ImageComboItem(Me.Text)
End If
Else
If TypeOf Me.Items(e.Index) Is ImageComboItem Then
lItem = DirectCast(Me.Items(e.Index), ImageComboItem)
lPadding = 1
Else
lItem = New ImageComboItem( _
MyBase.GetItemText(Me.Items(e.Index)))
End If
End If

If m_ImageList IsNot Nothing Then
lImgSize = m_ImageList.ImageSize
End If

' Calc item indentation
If CBool(e.State And DrawItemState.ComboBoxEdit) Then
lIndentationOffset = lImgSize.Width
lImageIndentation = 0
Else
lIndentationOffset = lImgSize.Width * (lItem.Indentation + 1) + _
lPadding
lImageIndentation = lIndentationOffset - lImgSize.Width + lPadding
End If

' Get the font:
If lItem.Font Is Nothing Then
lFont = m_Font
Else
lFont = lItem.Font
End If

' Get forecolor:
If CBool(e.State And DrawItemState.Selected) OrElse _
lItem.ForeColor = Color.Empty Then
lForeColor = e.ForeColor
Else
lForeColor = lItem.ForeColor
End If

' Get items image:
If Me.ImageList IsNot Nothing Then
With Me.ImageList.Images
If .ContainsKey(lItem.ImageKey) Then
lImage = .Item(lItem.ImageKey)

ElseIf lItem.ImageIndex <> -1 AndAlso _
lItem.ImageIndex < .Count Then
lImage = .Item(lItem.ImageIndex)

End If
End With
End If

' Draw the background:
If CBool(e.State And DrawItemState.Selected) OrElse _
lItem.BackColor = Color.Empty Then
e.DrawBackground()

Else
Using lBrush As New SolidBrush(lItem.BackColor)
e.Graphics.FillRectangle(lBrush, e.Bounds)
End Using
End If

' Draw the icon:
If lImage IsNot Nothing Then
e.Graphics.DrawImage(lImage, _
e.Bounds.X + lImageIndentation, _
e.Bounds.Y)
End If

' Draw text:
lTextRect = New Rectangle(e.Bounds.X + lIndentationOffset, _
e.Bounds.Y, _
e.Bounds.Width - lIndentationOffset, _
e.Bounds.Height)
lTextFmt = New StringFormat(StringFormatFlags.NoWrap)
lTextFmt.Alignment = StringAlignment.Near
lTextFmt.LineAlignment = StringAlignment.Center
lTextFmt.Trimming = StringTrimming.EllipsisCharacter

Using lBrush As New SolidBrush(lForeColor)
e.Graphics.DrawString(lItem.Text, lFont, _
lBrush, lTextRect, lTextFmt)
End Using

MyBase.OnDrawItem(e)

If m_DropDownHeight <> 0 Then
Me.DropDownHeight = m_DropDownHeight
End If
End Sub

Protected Overrides Sub OnMeasureItem( _
ByVal e As System.Windows.Forms.MeasureItemEventArgs)
Dim lNewHeight As Integer
Dim lCount As Integer

If Me.ImageList IsNot Nothing Then
lNewHeight = Me.ImageList.ImageSize.Height + 2
End If

If lNewHeight > e.ItemHeight Then
e.ItemHeight = lNewHeight
End If

lCount = Me.Items.Count

If lCount > Me.MaxDropDownItems Then
lCount = Me.MaxDropDownItems
End If

m_DropDownHeight = e.ItemHeight * lCount + 3

MyBase.OnMeasureItem(e)
End Sub

End Class

''' <summary>
''' Represents a single ImageComboItem.
''' </summary>
''' <remarks></remarks>
Public Class ImageComboItem
Private m_BackColor As Color = Color.Empty
Private m_Text As String
Private m_ImageIndex As Integer = -1
Private m_ImageKey As String
Private m_Indentation As Integer
Private m_Font As System.Drawing.Font
Private m_ForeColor As Color = Color.Empty
Private m_Tag As Object

Public Property BackColor() As Color
Get
Return m_BackColor
End Get

Set(ByVal value As Color)
m_BackColor = value
End Set
End Property

Public Property Font() As System.Drawing.Font
Get
Return m_Font
End Get

Set(ByVal value As System.Drawing.Font)
m_Font = value
End Set
End Property

Public Property ForeColor() As System.Drawing.Color
Get
Return m_ForeColor
End Get

Set(ByVal value As System.Drawing.Color)
m_ForeColor = value
End Set
End Property

Public Property Tag() As Object
Get
Return m_Tag
End Get
Set(ByVal value As Object)
m_Tag = value
End Set
End Property

Public Property ImageIndex() As Integer
Get
Return m_ImageIndex
End Get
Set(ByVal value As Integer)
m_ImageIndex = value
End Set
End Property

Public Property ImageKey() As String
Get
Return m_ImageKey
End Get
Set(ByVal value As String)
m_ImageKey = value
End Set
End Property

Public Property Indentation() As Integer
Get
Return m_Indentation
End Get
Set(ByVal value As Integer)
m_Indentation = value
End Set
End Property

Public Property Text() As String
Get
Return m_Text
End Get
Set(ByVal value As String)
m_Text = value
End Set
End Property

Public Sub New(ByVal text As String)
Me.New(text, -1)
End Sub

Public Sub New(ByVal text As String, ByVal imageIndex As Integer)
Me.New(text, imageIndex, 0, Nothing)
End Sub

Public Sub New(ByVal text As String, _
ByVal imageIndex As Integer, _
ByVal indentation As Integer, _
ByVal font As System.Drawing.Font)
m_Text = text
m_ImageIndex = imageIndex
m_Indentation = indentation
m_Font = font
End Sub
End Class

In der Anwendung:

' Form1 mit ImageCombo1 und ImageList1 mit 3 Icons 16x16:
Public Class Form1

Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs _
) Handles MyBase.Load

ImageCombo1.ImageList = ImageList1

ImageCombo1.Items.Add(New ImageComboItem("Eintrag 1", 0))
ImageCombo1.Items.Add(New ImageComboItem("Eintrag 2", 1))
ImageCombo1.Items.Add(New ImageComboItem("Eintrag 3", 2))

End Sub
End Class

Thorsten Dörfler
Microsoft MVP Visual Basic

vb-hellfire visual basic faq | vb-hellfire - einfach anders
http://vb-faq.de/ | http://www.vb-hellfire.de/

Ähnliche fragen