Rubrik: Controls · DataGrid & DataGridView | VB-Versionen: VB2005, VB2008 | 13.06.08 |
Array an DataGridView binden Die Elemente eindimensionaler Arrays müssen eine Eigenschaft bereitstellen, um gebunden angezeigt/editiert werden zu können. | ||
Autor: Manfred Bohn | Bewertung: | Views: 20.359 |
ohne Homepage | System: Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
Das DataGridView-Steuerelement erlaubt die Bindung eindimensionaler Arrays durch Zuweisung auf die DataSource-Eigenschaft.
Leider klappt das nicht bei Arrays, die aus integrierten Datentypen bestehen.
Der Bindungsmanager wird nur aktiv, wenn die Array-Elemente eine Eigenschaft besitzen, zu der eine Datenspalte im Steuerelement erstellt werden kann.
Die Klasse cDouble kapselt einen Double-Wert. Eindimensionale Arrays, die aus Instanzen dieser Klasse erstellt worden sind, können angezeigt und editiert werden. (Man beachte, unter welchen Bedingungen Zugriffe über den Konstruktor, den cType-Operator oder über die Standard-Eigenschaft erfolgen - siehe Anwendungsbeispiel 'cDouble_Demo').
''' <summary> ''' Klasse zur Kapselung eines numerischen Wertes (Double) ''' Bereitstellung der 'Value'-Methode ''' </summary> Public Class cDouble ' Der aufbewahrte Wert Private gValue As Double ''' <summary> ''' Konstruktor mit Wertzuweisung ''' </summary> ''' <param name="value">zuzuweisender Wert</param> Public Sub New(ByVal value As Double) gValue = value End Sub Public Shared Widening Operator CType(ByVal value As Double) As cDouble ' automatische Erstellung von Instanzen (bei Zuweisung) Return New cDouble(value) End Operator Public Shared Widening Operator CType(ByVal value As cDouble) As Double Return value.gValue End Operator ''' <summary> ''' Zuweisung/Abfrage eines num. Wertes per Eigenschaft ''' </summary> Public Property Value() As Double ' Für die Bindung (verwendet von ILIST des Array) Get Return gValue End Get Set(ByVal value As Double) gValue = value End Set End Property End Class
Unter der Voraussetzung, dass im Formular ein DataGridView-Steuerelement namens 'dgv' vorhanden ist, sollte folgende Ereignisbehandlungsroutine hinzugefügt werden. (Sie informiert über Fehleingaben beim Editieren der Array-Elemente und fängt die Ausnahmen ab.)
Private Sub dgv_DataError(ByVal sender As Object, _ ByVal e As System.Windows.Forms.DataGridViewDataErrorEventArgs) _ Handles dgv.DataError MsgBox(e.Exception.Message + vbCrLf + vbCrLf + _ "Die ESC-Taste setzt zurück", vbExclamation) e.Cancel = True End Sub
Die praktische Anwendung der Klasse 'cDouble' bei der Bindung eines Array an das Steuerelement (namens 'dgv') zeigt der folgende Code (ergänzend wird das Klonen und Kopieren durchgeführt).
Public Sub cDouble_Demo() ' Erstellung eines Array Dim N As Integer = 100 Dim x(N) As cDouble ' Füllen mit Daten For i As Integer = 0 To N ' Der cType-Operator erstellt die Instanzen x(i) = 10000 * Rnd() Next i ' Warnung: Clone = flache Kopie (Klasseninstanzen) ' y-Elemente verweisen auf x-Elemente Dim y() As cDouble = x.Clone ReDim y(N) ' Hier werden 'echte' Kopien der Elemente erstellt For i As Integer = 0 To N ' Wert-Zuweisung per New-Konstruktor y(i) = New cDouble(x(i)) Next i ' Anzeige und Editieren des Array im Steuerelement ' Zugriff per Standardeigenschaft von 'cDouble' dgv.DataSource = x ' Für numerische Werte ist diese Einstellung günstiger dgv.Columns(0).DefaultCellStyle.Alignment = _ DataGridViewContentAlignment.BottomRight End Sub
Die Klasse 'cDouble' macht die Einschränkung, dass die Array-Elemente Double-Werte kapseln.
Wenn man spezifische Datentypen verwenden möchte, kann man auf eine sog. generische Klasse zurückgreifen. Die generische Klasse 'cAny' ist entsprechend der Klasse 'cDouble' programmiert, erfordert aber bei der Deklaration die Angabe eines bestimmten Datentyps.
''' <summary> ''' Die Klasse kapselt einen Wert und stellt dem ''' Bindungsmanager die Value-Methode bereit ''' </summary> ''' <typeparam name="entrytype">Wert (primitiver Datentyp)</typeparam> Public Class cAny(Of entrytype) ' Alternative: falls nur Werttypen erwünscht sind ' Public Class cAny(Of entrytype As Structure) Private gValue As entrytype Public Sub New() gValue = Nothing End Sub ''' <summary> ''' Konstruktor mit Wertzuweisung ''' </summary> ''' <param name="value">zuzuweisender Wert</param> Public Sub New(ByVal value As entrytype) gValue = value End Sub Public Shared Widening Operator CType(ByVal value As entrytype) As cAny(Of entrytype) ' automatische Erstellung von Instanzen (bei Zuweisung) Dim x As New cAny(Of entrytype) x.Value = value Return x End Operator Public Shared Widening Operator CType(ByVal value As cAny(Of entrytype)) As entrytype Return value.gValue End Operator ''' <summary> ''' Eigenschaft zur Erstellung einer ''' Datenspalte bei der Bindung ''' </summary> Public Property Value() As entrytype ' (verwendet von ILIST: 'Item' des Array) Get Return gValue End Get Set(ByVal value As entrytype) gValue = value End Set End Property End Class
Instanzen der generischen Klasse können verschiedene Datentypen kapseln, je nach Deklaration. Man beachte, dass es vom EntryType des Array abhängt, welche Werte beim Editieren eingegeben werden können. Der Bindungsmanager überwacht die Zulässigkeit der Zuweisungen. (Der Beispielcode 'cAny_Demo' enthält einige ergänzende Hinweise zum Formatieren der Werte und zur Einstellung der Eigenschaften der erzeugten Spalte.)
Nicht jedes Steuerelement, das eine DataSource-Eigenschaft besitzt, ist auch zur Anzeige des Array geeignet bzw. befähigt.
Public Sub cAny_Demo() ' Erstellung von Arrays verschiedener Datentypen Dim N As Integer = 100 Dim dbl(N) As cAny(Of Double) Dim dec(N) As cAny(Of Decimal) Dim byt(N) As cAny(Of Byte) Dim str(N) As cAny(Of String) Dim bol(N) As cAny(Of Boolean) Dim s As String ' Füllen der Arays mit Daten For i As Integer = 0 To N ' Der cType-Operator erstellt die Instanzen dbl(i) = 10000 * Rnd() dec(i) = CDec("1E9") * CDec(Rnd()) + CDec(Rnd()) ' damit die Dezimal-Kommas untereinander stehen ' wenn keine Format benutzt wird (siehe unten) dec(i) = CDec(dec(i).Value.ToString("F10")) str(i) = "Element: " + Format(i, "000") If Rnd() > 0.5 Then bol(i) = True byt(i) = CByte(Rnd() * 250 + 1) Next i ' Warnung: Clone = flache Kopie (Klasseninstanzen) ' y-Elemente verweisen auf x-Elemente Dim dbl2() As cAny(Of Double) = dbl.Clone ReDim dbl2(N) ' Hier werden 'echte' Kopien der Elemente erstellt For i As Integer = 0 To N ' Wert-Zuweisung per New-Konstruktor dbl2(i) = New cAny(Of Double)(dbl(i)) Next i ' Ein Array für die Bindung an das Steuerelement auswählen ' dgv.DataSource = dbl dgv.DataSource = dec ' dgv.DataSource = str ' dgv.DataSource = bol ' Checkboxen werden angezeigt ' dgv.DataSource = byt ' Für numerische Werte sind folgende Einstellungen günstig ' (Spalte 0 ist vom Bindungsmanager erstellt worden) ' Zahlen- und Textausrichtung dgv.Columns(0).DefaultCellStyle.Alignment = _ DataGridViewContentAlignment.MiddleRight ' Spaltenbreite (Pixel) dgv.Columns(0).Width = 200 ' Schriftart dgv.Columns(0).DefaultCellStyle.Font = _ New Font("Arial", 12, FontStyle.Bold) ' selbsterstellter Grauton als Hintergrund in jeder 2. Zeile dgv.AlternatingRowsDefaultCellStyle.BackColor = _ Color.FromArgb(255, 235, 235, 235) ' zur Formatierung numerischer Werte: ' (wird beim Editieren automatisch eingerichtet) dgv.Columns(0).DefaultCellStyle.Format = "0.000000" End Sub