VB.NET-Tipp 0088: Combobox-Features - Befüllung, Darstellung, Databinding
von Spatzenkanonier
Beschreibung
Häufig nicht bekannt ist die Tatsache, dass Comboboxen nicht nur Strings enthalten können, sondern problemlos jede Art von Objekt. Liegen die Einträge in geeigneten Auflistungen vor (IList / IList(Of T)), kann man anstelle einer Befüllungs-Schleife einfach die Auflistung selbst als DataSource zuweisen. Der Anzeige-Text der Einträge kann mit Festlegung eines DisplayMembers und/oder eines Formatstrings nachhaltig beeinflusst werden. Verwendung von DataBinding kann die Verarbeitung des SelectedIndexChanged-Ereignisses erübrigen und stellt die für aufwändige Oberflächen günstigere Trennung von Ansicht und Daten her.
Dieser Tipp demonstriert die oben beschriebene Datenbindung und zeigt, auf welche Weise Daten zu einem Combobox-Steuerelement hinzugefügt werden können.
Anmerkung: Die gezeigten Features sind gleichfalls auf Listboxen anwendbar.
Schwierigkeitsgrad: | Framework-Version(en): .NET Framework 1.0, .NET Framework 1.1, .NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5 | .NET-Version(en): Visual Basic 2002, Visual Basic 2003, Visual Basic 2005, Visual Basic 2008 | Download: |
' Dieser Quellcode stammt von http://www.activevb.de ' und kann frei verwendet werden. Für eventuelle Schäden ' wird nicht gehaftet. ' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. ' Ansonsten viel Spaß und Erfolg mit diesem Source! ' Projektversion: Visual Studio 2005 ' Option Strict: An ' ' Referenzen: ' - System ' - System.Data ' - System.Drawing ' - System.Windows.Forms ' - System.Xml ' ' Imports: ' - Microsoft.VisualBasic ' - Microsoft.VisualBasic.ControlChars ' - System ' - System.Collections ' - System.Collections.Generic ' - System.Data ' - System.Diagnostics ' - System.Drawing ' - System.Drawing.Drawing2D ' - System.Windows.Forms ' ' ############################################################################## ' ################################# Canvas.vb ################################## ' ############################################################################## Imports System.ComponentModel ''' <summary>einfaches Control zur Anzeige eines GraphicsPathes</summary> Public Class Canvas : Inherits Control Private _TemplatePath As GraphicsPath Private _DrawPath As New GraphicsPath Private _Matrix As New Matrix ''' <summary> ''' Canvas zeigt eine auf seine Größe skalierte Kopie dieses ''' GraphicsPathes an ''' </summary> <Bindable(True)> _ Public Property TemplatePath() As GraphicsPath ' Das Bindable(True)-Attribut ermöglicht, Databinding auch im ' Form-Designer einzustellen Get Return _TemplatePath End Get Set(ByVal NewValue As GraphicsPath) If _TemplatePath Is NewValue Then Return _TemplatePath = NewValue ApplyChanges() End Set End Property Protected Overrides Sub OnSizeChanged(ByVal e As System.EventArgs) MyBase.OnSizeChanged(e) ApplyChanges() End Sub Protected Overrides Sub OnPaint( _ ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) If _TemplatePath Is Nothing Then Return e.Graphics.DrawPath(Pens.Red, _DrawPath) End Sub Private Sub ApplyChanges() ' Lege in _DrawPath eine auf meine Größe skalierte Kopie von ' _TemplatePath(an) If _TemplatePath Is Nothing Then Return _Matrix.Reset() Dim Bounds As RectangleF = _TemplatePath.GetBounds Dim Sz As SizeF = MyBase.ClientSize - New Size(1, 1) With _TemplatePath.GetBounds ' ObenLinks auf Nullpunkt schieben _Matrix.Translate(-.X, -.Y, MatrixOrder.Append) ' Skalieren _Matrix.Scale(Sz.Width / .Width, _ Sz.Height / .Height, MatrixOrder.Append) End With _DrawPath.Reset() _DrawPath.AddPath(_TemplatePath, False) _DrawPath.Transform(_Matrix) MyBase.Invalidate() End Sub Protected Overrides Sub Dispose(ByVal disposing As Boolean) If disposing AndAlso _DrawPath IsNot Nothing Then _DrawPath.Dispose() _Matrix.Dispose() _DrawPath = Nothing End If MyBase.Dispose(disposing) End Sub End Class ' ############################################################################## ' ############################ frmComboFeatures.vb ############################# ' ############################################################################## Public Class frmComboFeatures Private Pts As PointF() = New PointF() { _ New PointF(-4, 0), New PointF(-3, -3), New PointF(0, -4), _ New PointF(3, -3), New PointF(4, 0), New PointF(3, 3), _ New PointF(0, 4), New PointF(-3, 3)} Private Sub Form_Load(ByVal sender As Object, _ ByVal e As EventArgs) Handles Me.Load SetupTab1() SetupTab2() End Sub Private Sub SetupTab1() ' Die bekannteste Art eine Combo zu befüllen ist wohl jeden ' anzuzeigenden String einzeln hinzuzufügen For Each Pt As PointF In Pts ComboBox1.Items.Add(Pt.ToString) Next ComboBox1.SelectedIndex = 0 ' Man kann aber einfacher die Objekte selbst hinzufügen ' Zusätzlicher Vorteil: Über die Items-Property können nun nicht nur ' String-Repräsantionen der Objekte abgerufen werden, sondern die ' Objekte selbst. ' In diesem Fall bedient sich die Combobox zur Ermittlung der Anzeige ' automatisch der .ToString()-Funktion der Objekte. For Each Pt As PointF In Pts ComboBox2.Items.Add(Pt) Next ComboBox2.SelectedIndex = 0 ' Über die "DisplayMember"-Eigenschaft der Combo kann bestimmt werden, ' daß nicht Item.ToString() dargestellt wird, sondern die spezifizierte ' Eigenschaft. Hier wird Pointf.X angezeigt ' (Pointf.Y dadurch ausgeblendet) ComboBox3.DisplayMember = "X" For Each Pt As PointF In Pts ComboBox3.Items.Add(Pt) Next ComboBox3.SelectedIndex = 0 ' Liegen die Daten bereits in einer Auflistung vor (hier: Array), so ' kann man diese gegebenenfalls direkt als DataSource angeben. Diese ' Variante ist der erste Schritt zum Databinding. ' Vorraussetzung: Die Auflistung muß die IList- oder IList(Of T)- ' Schnittstelle implementieren (derlei Informationen erfährt man im ' ObjectBrowser). Zusätzlich kann die Darstellung durch Angabe eines ' FormatStrings beeinflußt werden ComboBox4.DisplayMember = "Y" ' Zeige Zahlenwerte als Währung an ComboBox4.FormatString = "c" ComboBox4.DataSource = Pts End Sub Private Sub SetupTab2() ' Hier will ich verschiedene GraphicsPathes mit Namen verknüpfen. Die ' Namen sollen in der Combo angezeigt werden, die Pathes im ' Canvas-Control. Statt einer eigens implementierten Daten-Klasse ' nehme ich mir als Name-Path-Container einfach ' KeyValuePair(Of T1, T2) her Dim Entries As New List(Of KeyValuePair(Of String, GraphicsPath)) Dim GP As New GraphicsPath GP.AddEllipse(0, 0, 4, 4) Entries.Add(New KeyValuePair(Of String, GraphicsPath)("Ellipse", GP)) GP = New GraphicsPath GP.AddRectangle(New Rectangle(0, 0, 4, 4)) Entries.Add(New KeyValuePair(Of String, GraphicsPath)("Rectangle", GP)) GP = New GraphicsPath GP.AddLine(0, 0, 4, 4) Entries.Add(New KeyValuePair(Of String, GraphicsPath)("Line", GP)) GP = New GraphicsPath GP.AddLines(Pts) Entries.Add(New KeyValuePair(Of String, GraphicsPath)("Lines", GP)) GP = New GraphicsPath GP.AddPolygon(Pts) Entries.Add(New KeyValuePair(Of String, GraphicsPath)("Polygon", GP)) GP = New GraphicsPath GP.AddBeziers(New PointF() {Pts(0), Pts(1), Pts(7), Pts(2), Pts(5), _ Pts(3), Pts(4)}) Entries.Add(New KeyValuePair(Of String, GraphicsPath)("Beziers", GP)) ' ComboBox5 wird per .DataSource-Property die Steuerung des ' DataBindings übertragen, an welches Canvas1 ebenfalls angeschlossen ' wird. Auf diese Weise kann ohne weiteren Code mit der Combo gewählt ' werden, was Canvas1 anzeigt. ComboBox5.DisplayMember = "Key" ComboBox5.DataSource = Entries Canvas1.DataBindings.Add("TemplatePath", Entries, "Value") End Sub End Class
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.