vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
vb@rchiv Offline-Reader - exklusiv auf der vb@rchiv CD Vol.4  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik: Datenbanken · DataSet/DataTable   |   VB-Versionen: VB.NET06.10.05
Datenanzeige bei Bindung an Datagrid

Einstellung der Datenanzeige bei Datenbindung an das Datagrid-Steuerelement

Autor:   Manfred BohnBewertung:     [ Jetzt bewerten ]Views:  31.514 
ohne HomepageSystem:  WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt auf CD 

Problem:
Das Anzeigen und Editieren von Daten, die aus einer Datenbank oder einer Datei in eine Instanz des DataTable-Objekts übertragen worden sind, ist bei VB.NET relativ einfach. Man weist die DataTable-Instanz der DataSource-Eigenschaft eines Datagrid-Steuerelements zu.

Die Art wie die Daten dabei dargestellt werden, ergibt sich aus automatisch erstellten GridColumnStyles-Objekten. In vielen Fällen sind die dabei verwendeten Standard-Einstellungen aber nicht besonders zweckmäßig. Einige Beispiele:

  • alle Spalten werden - unabhängig vom Dateninhalt - in einer Standardbreite angezeigt;
  • auch Spalten mit numerischen Daten sind nach links ausgerichtet;
  • Spalten mit boolschen Daten werden als CheckBox angezeigt (dabei entspricht der grau unterlegte 'Zwischenzustand' einem fehlenden Daten-Wert);
  • fehlende Daten-Werte erscheinen in der 'DataGridTextBoxColumn' als '(Null)';
  • in Spalten des Datentyps 'DateTime' wird nur das Datum angezeigt, Zeitangaben werden ggf. unterdrückt und können deshalb nicht editiert werden;
  • die Edit-Textboxen der Spalten ermöglichen 'Löschen' und 'Einfügen' über das Kontextmenü;
  • die Option alternierender Hintergrund-Farben für die Datenzeilen wird nicht genutzt;
  • die Größe des verwendeten Default-Fonts bei der Anzeige der Daten orientiert sich an der Windows-Einstellung für Menüs und Dialogfelder - ist deshalb meist recht klein;
  • u.a.

Die automatisierte Anzeige kann man umgehen, wenn man der TableStyles-Auflistung des Datagrid-Steuerelements VOR Belegung der Datasource-Eigenschaft eine TableStyles-Objektinstanz hinzufügt, deren Mapping-Eigenschaft mit dem Namen der Datatable-Instanz belegt wird. Die Eigenschaften der Tablestyles-Instanz können dann in geeigneter Weise eingestellt werden. Die GridColumnStyles-Auflistung dieser Instanz ist zusätzlich für alle Tabellen-Spalten mit Instanzen der Klasse 'DatagridTextBoxColumn' zu füllen, deren Eigenschaften dann ebenfalls zugewiesen werden können. Diese Vorgehensweise ist gewöhnungsbedürftig - insbesondere was das Zusammenwirken der beteiligten Objekte betrifft. Einige Einstellungen müssen nämlich (anscheinend ??) direkt im Datagrid vorgenommen werden, weil die entsprechende TableStyles-Eigenschaft ignoriert wird.

Vorschlag:
Der Demo-Routine 'DataTable2DataGrid' ist eine mit Daten-Spalten gefüllte Instanz eines DataTable-Objekts zu übergeben und der Verweis auf ein DataGrid-Steuerelement. Der optionale Parameter 'BoolCheckBox' steuert, ob 'boolsche' Spalten als Checkbox (true) oder als Textbox (false) angezeigt werden. Falls die Routine scheitert, wird im Parameter 'Meldung' der Grund dafür angegeben.

Im einzelnen wird gezeigt

  • wie man den bei der Datenanzeige verwendeten Font vorgeben kann;
  • wie die Darstellungs-Farben gewählt werden; wie man Datum UND Uhrzeit in 'DateTime'-Spalten anzeigen und danach editieren kann (Format-Eigenschaft);
  • wie die geeignete Spaltenbreite ermittelt und eingestellt wird;
  • wie man die Ausrichtung des Inhalts der Datenspalten vornimmt (numerisch = rechts);
  • wie man auf die Eigenschaften der Edit-Textbox der Daten-Spalten zugreift;
  • wie man das Kontextmenü der Edit-Textbox unterdrückt;
  • wie man den 'Nulltext' definiert, der bei fehlenden Werten in der Spalte angezeigt wird.

Hinweise:

  • Bei der Zuweisung einer DataTable-Instanz auf die Datatsource-Eigenschaft wird zwar ggf. automatisch ein Standard-Tabellenstil erzeugt, aber nicht der TableStyles-Auflistung hinzugefügt. Will man auf die automatisch erstellten Anzeige-Objekte zugreifen, muss eine TableStyles-Instanz erstellt werden, deren Mapping-Eigenschaft auf den Tabellennamen der DataTable-Instanz eingestellt wird. Erst NACH Festlegung der Datasource-Eigenschaft des Datagrid darf diese Instanz der TableStyles-Auflistung hinzugefügt werden.
     
  • In der VB-IDE wird für die TableStyles-Auflistung des Datagrid-Steuerelements normalerweise die 'Count'-Eigenschaft nicht angezeigt, diese Eigenschaft ist aber trotzdem (schreibgeschützt) vorhanden. Das gilt auch für die 'GridColumnStyles'-Auflistung des DataGridTableStyle-Objekts. Damit diese sog. "Infrastruktur"-Eigenschaften angezeigt werden, ist im Menü "Extras -> Optionen -> Texteditor -> Basic -> Allgemein" die Checkbox "Erweiterte Member ausblenden" zu deaktivieren.
     
  • Um eine Spalte in der Anzeige auszublenden, notiert man die aktuelle Spaltenbreite in der GridColumnStyles-Auflistung und setzt die 'Width'-Eigenschaft dann auf 0; das Wieder-Einblenden erfolgt durch Zuweisung der gespeicherten Spaltenbreite. Um eine Spalte aus der Anzeige zu löschen empfiehlt die MSDN die Verwendung der 'RemoveAt'-Methode der GridColumnStyles-Auflistung. Das ist aber nicht empfehlenswert, weil dadurch die Instanz mit den Einstellungen zur Anzeige der Spalte gelöscht wird.

Spaltenposition:
Die Reihenfolge, in der die Daten-Spalten angezeigt werden, richtet sich nach der Abfolge in der 'gemappten' GridColumnStyles-Auflistung. Anscheinend existieren aber keine Methoden, die zur Laufzeit die programmgesteuerte Verschiebung der Items in dieser Liste unterstützen. Die Routine 'SpaltenAnzeigePosition' erwartet eine Instanz des TableStyle-Objekts. Im zweiten Parameter ist eine 'nullbasierte' Spaltenposition zu übergeben, die an die 'Neue_Position' verschoben werden soll. Die GridColumnStyles-Auflistung wird - entsprechend dieser Verschiebung - komplett umgeschichtet und dabei die spaltenbezogenen Items entsprechend angeordnet. Nach Durchführung von 'DataTable2DataGrid' für das Steuerelement 'Datagrid1' kann die Abfolge der Spalten programmgesteuert umgestellt werden durch den Aufruf:

Call SpaltenAnzeigePosition(DataGrid1.TableStyles(0), Aktuelle_Position, Neue_Position)

Diese Funktion scheitert ( = Rückgabe: false), wenn unplausible Parameter übergeben werden.

' ===============================================================================================
' Start Quellcode
' ===============================================================================================
 
Public Function DataTable2DataGrid( _
  ByVal dt As System.Data.DataTable, _
  ByVal dg As System.Windows.Forms.DataGrid, _
  Optional ByVal BoolCheckBox As Boolean = False, _
  Optional ByRef Meldung As String = "") As Boolean
 
  ' Erstellung eines TableStyle-Objekts vor der 
  ' Belegung des 'Datagrid' mit dem Inhalt der 'DataTable'
  ' danach Bindung der Tabelle 'dt' an 'dg'
 
  Dim ci, si As Integer
  Dim ts As System.Windows.Forms.DataGridTableStyle
  Dim col As System.Data.DataColumn
  Dim tbc As DataGridTextBoxColumn
  Dim cm As New System.Windows.Forms.ContextMenu
 
  Const cMissingDisplay As String = "(fehlt!)"
 
  Try
    If dg Is Nothing Or dt Is Nothing Then
      Meldung = "Parameter fehlt"
      Exit Function
    End If
 
    If dt.TableName = "" Or dt.Columns.Count < 1 Then
      Meldung = "Kein Tafelschema"
      Exit Function
    End If
 
    ' Datagrid initialisieren
    With dg
      .DataBindings.Clear()
      .TableStyles.Clear()
      .DataSource = Nothing
 
      ' Überschrift der Anzeige festlegen 
      ' ( =Tabellenname [Spalten, Zeilen] )
      .CaptionVisible = True
      .CaptionText = "Tabelle: " + dt.TableName + _
        " [" + CStr(dt.Columns.Count) + " * " + _
        CStr(dt.Rows.Count) + "]"
 
      ' einheitlichen Font im Datagrid definieren
      .Font = New System.drawing.Font("Arial", 10, FontStyle.Bold)
      .HeaderFont = .Font : .CaptionFont = .Font
 
      ' geeignete Höhe für 3D-Editbox einrichten
      .PreferredRowHeight = 26
 
      ' Breite der linken Spalte (=RowHeader) festlegen 
      .RowHeaderWidth = 20
    End With
 
    ' TableStyle-Objekt für die Tafel erstellen
    ts = New System.Windows.Forms.DataGridTableStyle
    ' ts.MappingName = dt.TableName
    dg.TableStyles.Add(ts)
 
    ' Einstellung der TableStyle-Instanz
    With ts
      ' für Verbindung zur Tabelle
      .MappingName = UCase(dt.TableName)
 
      ' Rahmenzellen sichtbar machen 
      .ColumnHeadersVisible = True
      .RowHeadersVisible = True
 
      ' Sortieren und Editieren in der Tabelle erlauben
      .AllowSorting = True : .ReadOnly = False
 
      ' Farben des Datenbereichs festlegen
      .ForeColor = System.Drawing.Color.Black
      .BackColor = System.Drawing.Color.WhiteSmoke
      .AlternatingBackColor = System.Drawing.Color.LightGray
 
      ' Farben der Spalten-Überschrift festlegen
      .HeaderBackColor = System.Drawing.Color.DarkGray
      .HeaderForeColor = System.Drawing.Color.White
 
      ' Farbe der Spalten-Trennlinien festlegen
      .GridLineColor = System.Drawing.Color.BlueViolet
      .GridLineStyle = DataGridLineStyle.Solid
 
      ' Farbe der selektierten und der markierten
      ' Zellen festlegen
      .SelectionForeColor = System.Drawing.Color.White
      .SelectionBackColor = System.Drawing.Color.MediumAquamarine
 
      ' Datagrid-Font in TableStyle-Instanz übernehmen
      .HeaderFont = dg.Font
      .PreferredRowHeight = dg.PreferredRowHeight
 
      ' Style-Objekte für die einzelnen Spalten erstellen 
      For ci = 0 To dt.Columns.Count - 1
 
        ' Verweis auf Spalten-Objekt besorgen
        col = dt.Columns(ci)
 
        ' Style-Objekt für Spalte 'i' erstellen
        If BoolCheckBox And InStr(UCase(col.DataType.ToString), "BOOL") > 0 Then
          ' Boolsche Spalte als Checkbox anzeigen
          si = .GridColumnStyles.Add(New DataGridBoolColumn)
          ' erforderliche Anzeige-Breite der Checkbox-Spalte 
          .GridColumnStyles(si).Width = SpaltenBreite(col, dg)
 
        Else
          ' Spalte wird als TextBox dargestellt
          si = .GridColumnStyles.Add(New DataGridTextBoxColumn)
 
          ' Verweis auf das aktuelle SpaltenStyle-Objekt besorgen
          tbc = .GridColumnStyles(si)
 
          ' Anzeige der Spalte 'ci' einstellen
          With tbc
            If InStr(UCase(col.DataType.ToString), "DATETIME") > 0 Then
              ' Format für Datum(kurz) / Zeit(lang) einstellen
              .Format = "G"
            End If
 
            ' erforderliche Anzeige-Breite der Spalte 'Col' 
            ' ermitteln, unter Beachtung der 'Font'-Einstellung
            ' des Datagrid
            .Width = SpaltenBreite(col, dg)
 
            If InStr(UCase(col.DataType.ToString), "STRING") = 0 Then
              ' Rechts-Ausrichtung der Spalte einstellen
              .Alignment = HorizontalAlignment.Right
              ' vollständige Sichtbarkeit der Spalten-
              ' Überschrift sicherstellen
              ' (bei manchen Einstellungen entbehrlich!)
              .HeaderText = "_"
            Else
              .Alignment = HorizontalAlignment.Left
            End If
 
            ' Anzeigeform für fehlende Daten-Werte 
            ' in der Spalte festlegen
            .NullText = cMissingDisplay
 
            ' Editieren der Daten-Spalte erlauben
            .ReadOnly = False
 
            ' Eigenschaften der Edit-Textbox der Spalte einrichten
            With .TextBox
              ' Farbe der 3D-Edit-Box der Spalte festlegen
              .ForeColor = System.Drawing.Color.Red
              .BackColor = System.Drawing.Color.Yellow
              ' 3D-Rahmen anfordern 
              .BorderStyle = BorderStyle.Fixed3D
              ' Standard-KontextMenü unterdrücken
              .ContextMenu = cm
            End With
          End With  ' tbc
        End If        ' TextboxColumn oder BoolColumn
 
        ' Verbindung zur Daten-Spalte herstellen
        With .GridColumnStyles(si)
          .MappingName = col.ColumnName
          .HeaderText = col.ColumnName + .HeaderText
        End With
      Next ci
    End With
 
    ' Datentabelle in das Datagrid 'dg' eintragen:
    ' Es erfolgt automatisch eine Verknüpfung mit der
    ' gemappten DataGridTableStyle-Instanz 'ts'
    dg.DataSource = dt
    DataTable2DataGrid = True : Meldung = ""
  Catch ex As Exception
    Meldung = ex.Message.ToString
  End Try
End Function
Private Function SpaltenBreite(ByVal col As DataColumn, _
  ByVal dg As DataGrid) As Integer
 
  ' Die benötigte Anzeige-Spaltenbreite der 
  ' Datacolumn 'col' im Datagrid 'dg' wird ermittelt
  ' Beachtung der Mindestbreite, der Breite des Spaltenbezeichners
  ' und ggf. der maximal möglichen Länge der Spaltendaten (numerisch)
 
  Dim lsm As System.Drawing.SizeF
  Dim wh, wn As Integer
  Dim str As String
  Const cMindestBreite As Integer = 50
 
  ' Rückgabe initialisieren
  SpaltenBreite = 0
 
  ' Eingabe prüfen
  If dg Is Nothing Or col Is Nothing Then Exit Function
 
  ' Breite des Spaltenbezeichners ermitteln
  ' unter Beachtung der 'Font'-Einstellung
  lsm = dg.CreateGraphics.MeasureString(col.ColumnName + "___", dg.Font)
  wh = lsm.Width
 
  ' Mindestbreite der Spalte sicherstellen
  If wh < cMindestBreite Then wh = cMindestBreite
 
    ' Maximale Breite des Datentyps der Spalte ermitteln
    ' (Ausnahme: Strings)
    str = Type_MaxLänge(col.DataType) : wn = 0
    If str <> "" Then
      lsm = dg.CreateGraphics.MeasureString(str + "__", dg.Font)
      wn = lsm.Width
    End If
 
    ' Breite der Spalte einstellen
    If wn < wh Then
      SpaltenBreite = wh  ' Breite des Spaltenbezeichners
    Else
      SpaltenBreite = wn  ' max. Breite der Spaltendaten 
    End If
End Function
Private Function Type_MaxLänge(ByVal st As System.Type) As String
 
  ' Hilfsfunktion für Routine 'SpaltenBreite'
  ' Die Routine ermittelt für den übergebenen Datentyp
  ' den zugehörigen String maximaler Länge
 
  Dim ms, str As String
  ms = "" : str = UCase(st.ToString)
  If InStr(str, "BYTE") > 0 Then ms = CStr(System.Byte.MaxValue)
  If InStr(str, "INT16") > 0 Then ms = CStr(System.Int16.MinValue)
  If InStr(str, "INT32") > 0 Then ms = CStr(System.Int32.MinValue)
  If InStr(str, "INT64") > 0 Then ms = CStr(System.Int64.MinValue)
  If InStr(str, "SINGLE") > 0 Then ms = CStr(System.Single.MinValue)
  If InStr(str, "DOUBLE") > 0 Then ms = CStr(System.Double.MinValue)
  If InStr(str, "DECIMAL") > 0 Then ms = CStr(System.Decimal.MinValue)
  If InStr(str, "DATETIME") > 0 Then ms = Format(System.DateTime.MaxValue, "u")
  Type_MaxLänge = ms
 
End Function
Public Function SpaltenAnzeigePosition( _
  ByRef ts As DataGridTableStyle, _
  ByVal Aktuelle_Position As Integer, _
  ByVal Neue_Position As Integer) As Boolean
 
  ' Verschiebung der Anzeigeposition einer Spalte
  ' durch Modifikation der GridColumnstyles-Auflistung
  ' Die Positionsangaben werden von 0 (links) bis 
  ' Spaltenzahl-1 (rechts) erwartet
 
  Dim i, sz As Integer
  Dim temp_ts As New DataGridTableStyle
  Dim temp_ts_move As New DataGridTableStyle
 
  Try
    ' Eingabeparameter prüfen
    If ts Is Nothing Then Exit Function
    ' Zahl der Spalten feststellen
    sz = ts.GridColumnStyles.Count
    If sz < 2 Then Exit Function
    If Aktuelle_Position < 0 Or Aktuelle_Position > sz - 1 Or _
      Neue_Position < 0 Or Neue_Position > sz - 1 Then
      Exit Function
    End If
 
    If Aktuelle_Position = Neue_Position Then
      ' nichts zu tun
      SpaltenAnzeigePosition = True : Exit Function
    End If
 
    ' Spalten-Anzeige an bisheriger Position notieren
    temp_ts_move.GridColumnStyles.Add( _
    ts.GridColumnStyles(Aktuelle_Position))
 
    With temp_ts
      If Neue_Position = 0 Then
        ' Spalte ganz links anzeigen
        .GridColumnStyles.Add( _
        temp_ts_move.GridColumnStyles(0))
      End If
 
      For i = 0 To sz - 1
        If .GridColumnStyles.Count = Neue_Position Then
          ' Spalte von alter an neue Position verschieben
          .GridColumnStyles.Add(temp_ts_move.GridColumnStyles(0))
        End If
        If i <> Aktuelle_Position Then
          ' Spalten-Angaben übertragen
          .GridColumnStyles.Add(ts.GridColumnStyles(i))
        End If
      Next i
 
      If Neue_Position = sz - 1 Then
        ' Spalte ganz rechts anzeigen
        .GridColumnStyles.Add(temp_ts_move.GridColumnStyles(0))
      End If
 
      ' GridColumnStyles-Auflistung übertragen
      ts.GridColumnStyles.Clear()
      For i = 0 To sz - 1
        ts.GridColumnStyles.Add(.GridColumnStyles(i))
      Next i
    End With
 
    SpaltenAnzeigePosition = True
  Catch ex As Exception
  End Try
 
End Function
 
' ===============================================================================================
' Ende Quellcode
' ===============================================================================================

Dieser Tipp wurde bereits 31.514 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Neue Diskussion eröffnen

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6
(einschl. Beispielprojekt!)

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel