EDM: DataGrid als Datenblatt

Wenn Sie ein Abonnement des Magazins 'DATENBANKENTWICKLER' besitzen, können Sie sich anmelden und den kompletten Artikel lesen.
Anderenfalls können Sie das Abonnement hier im Shop erwerben.

EDM: DataGrid als Datenblatt

Wer von Access kommt und Datenbankanwendungen mit Visual Studio programmieren möchte, vermisst vermutlich das einfache Datenblatt, das man unter Access mit wenigen Mausklicks zusammenstellen konnte. Dieses zeigt nicht nur die Datensätze der als Datenherkunft verwendeten Tabelle oder Abfrage an, sondern bietet auch die Möglichkeit, die enthaltenen Daten zu ändern, zu löschen oder durch neue Datensätze zu ergänzen. Dies wollen wir in diesem Artikel durch den Einsatz eines entsprechend programmierten DataGrid-Steuerelements nachbauen.

Beispieldaten

In den Artikeln Von Access zu Entity Framework: Datenmodell und Von Access zu Entity Framework: Daten haben wir gezeigt, wie Sie ein Entity Data Modell auf Basis eines Access-Datenmodells erstellen und die Daten für die daraus zu erzeugenden Tabellen in eine Seed-Methode schreiben. Im Beispielprojekt dieses Artikels haben wir das Entity Data Model und die Klasse mit der Seed-Methode bereits angelegt, sodass Sie nach dem Kopieren des Projektordners auf Ihren Rechner einfach nur den die Anweisung Update-Database in der Paket-Manager-Konsole ausführen müssen. Dadurch sollte automatisch eine Datenbank für den in der Verbindungszeichenfolge angegebenen SQL Server, hier LocalDb, angelegt und mit den angegebenen Tabellen und Daten gefüllt werden.

Fenster mit DataGrid anlegen

Wir wollen gleich ein eigenes Fenster für dieses Beispiel anlegen, das Sie dann über eine Schaltfläche vom Fenster MainWindow aus aufrufen können. Dazu legen wir die folgende Schaltfläche in diesem Fenster an:

<Grid>
     <Button x:Name="btnProdukteDataGrid" Click="btnProdukteDataGrid_Click">DataGrid mit Produkten</Button>
</Grid>

Die Schaltfläche soll die folgende Ereignismethode aufrufen:

Private Sub btnProdukteDataGrid_Click(sender As Object, e As RoutedEventArgs)
     Dim wnd As Window
     wnd = New ProdukteDataGrid
     wnd.ShowDialog()
End Sub

Das neue Fenster nennen wir ProdukteDatagrid.xaml. Zunächst legen wir ein paar Elemente in der Code behind-Klasse an, der wir zunächst die Konstruktor-Methode hinzufügen:

Public Class ProdukteDataGrid
     Public Sub New()
     End Sub
End Class

Wir benötigen einen Verweis auf den Namespace System.Collections.ObjectModel:

Imports System.Collections.ObjectModel

In der Klasse definieren wir eine lokale Variable für die Kontextklasse sowie die Liste der Produkte:

Private dbContext As BestellverwaltungContext
Private m_Produkte As ObservableCollection(Of Produkt)

Die Liste der Produkte wollen wir über eine öffentliche Eigenschaft namens Produkte verfügbar machen:

Public Property Produkte() As ObservableCollection(Of Produkt)
     Get
         Return m_Produkte
     End Get
     Set(ByVal value As ObservableCollection(Of Produkt))
         m_Produkte = value
     End Set
End Property

Damit das DataGrid beim Öffnen direkt mit den Daten gefüllt wird, erweitern wir die Konstruktormethode mit diesen Anweisungen:

Public Sub New()
     InitializeComponent()
     dbContext = New BestellverwaltungContext
     Produkte = New ObservableCollection(Of Produkt)(dbContext.Produkte)
     DataContext = Me
End Sub

Darin füllen wir die Kontext-Variable und die List-Variable Produkte mit der Liste der Produkte. Schließlich stellen wir den DataContext auf die Code behind-Klasse ein. Wenn wir nun das Projekt starten und im Fenster MainWindow auf die Schaltfläche klicken, erscheint das DataGrid wie in Bild 1.

DataGrid mit den Daten der Tabelle Produkte

Bild 1: DataGrid mit den Daten der Tabelle Produkte

Kombinationsfelder anzeigen

Die Daten der Felder KategorieID und MehrwertsteuersatzID möchten wir gern aus den jeweils verknüpften Auflistungen Kategorien und Mehrwertsteuersaetze füllen. Außerdem wollen wir noch die Spaltenüberschriften anpassen. Das erledigen wir mit den folgenden Erweiterungen, wobei wir erst die Daten für die Kombinationsfelder in der Code behind-Klasse verfügbar machen. Dazu fügen wir zwei private Variablen für die Listen der Kategorien und der Mehrwertsteuersätze hinzu:

Private m_Kategorien As List(Of Kategorie)
Private m_Mehrwertsteuersaetze As List(Of Mehrwertsteuersatz)

Für beide richten wir entsprechende öffentliche Eigenschaften ein:

Public Property Kategorien As List(Of Kategorie)
     Get
         Return m_Kategorien
     End Get
     Set(ByVal value As List(Of Kategorie))
         m_Kategorien = value
     End Set
End Property
Public Property Mehrwertsteuersaetze As List(Of Mehrwertsteuersatz)
     Get
         Return m_Mehrwertsteuersaetze
     End Get
     Set(ByVal value As List(Of Mehrwertsteuersatz))
         m_Mehrwertsteuersaetze = value
     End Set
End Property

Schließlich füllen wir diese in der Konstruktor-Methode aus den entsprechenden DbSets:

Public Sub New()
     ...
     Kategorien = New List(Of Kategorie)(dbContext.Kategorien)
     Mehrwertsteuersaetze = New List(Of Mehrwertsteuersatz)(dbContext.Mehrwertsteuersaetze)
     DataContext = Me
End Sub

Damit stehen die Daten der Kategorien und der Mehrwertsteuersätze über die öffentlichen Variablen Kategorien und Mehrwertsteuersaetze für den Zugriff aus der XAML-Seite bereit. Diese passen wir nun wie folgt an. Zunächst stellen wir AutoGenerateColumns auf False ein, da wir die Spalten nun von Hand definieren:

<DataGrid x:Name="dgProdukte" ItemsSource="{Binding Produkte}" AutoGenerateColumns="False">

Dann folgen die einzelnen Spaltendefinitionen im DataGrid.Columns-Element:

     <DataGrid.Columns>
         <DataGridTextColumn Binding="{Binding Path=Name}" Header="Produkt"></DataGridTextColumn>

Das Kombinationsfeld realisieren wir als DataGridComboBocColumn-Element, für das wir den Header festlegen sowie das gebundene Feld der Datenquelle des DataGrids beziehungsweise des Fensters (SelectedValueBinding), den Namen des anzuzeigenden Feldes (DisplayMemberPath) und den Namen des gebundenen Feldes (SelectedValuePath):

         <DataGridComboBoxColumn Header="Kategorie" SelectedValueBinding="{Binding KategorieID}" DisplayMemberPath="Name" SelectedValuePath="ID">

Die Datenquelle für das Kombinationsfeld müssen wir über einen Umweg festlegen, indem wir die Eigenschaft ItemsSource manuell definieren und füllen. Die Daten beziehen wir dabei aus der entsprechenden Eigenschaft des übergeordneten Window-Elements. Dies legen wir sowohl für die Eigenschaft ElementStyle als auch für die Eigenschaft EditingElementStyle fest. Dabei liefert ElementStyle die Formatierung für den angezeigten Text des Kombinationsfeldes und EditingElementStyle die Formatierung für die Elemente in der Liste nach dem Aufklappen:

             <DataGridComboBoxColumn.ElementStyle>
                 <Style TargetType="{x:Type ComboBox}">
                 <Setter Property="ItemsSource" Value="{Binding Path=DataContext.Kategorien,                     RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
             </Style>
             </DataGridComboBoxColumn.ElementStyle>
             <DataGridComboBoxColumn.EditingElementStyle>
                 <Style TargetType="{x:Type ComboBox}">
                     <Setter Property="ItemsSource" Value="{Binding Path=DataContext.Kategorien,                         RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
                 </Style>
             </DataGridComboBoxColumn.EditingElementStyle>
         </DataGridComboBoxColumn>

Beim Kombinationsfeld für die Mehrwertsteuersätze ist noch eine weitere Information in Form eines zusätzlichen Setters erforderlich, und zwar die Angabe der Formatierung. Während die Mehrwertsteuersätze in Form der Werte 0,07 und 0,19 gespeichert sind, sollen diese als 7,00% und 19,00% im Kombinationsfeld erscheinen. Daher definieren wir hier zusätzlich den Setter für die Eigenschaft ItemStringFormat:

         <DataGridComboBoxColumn Header="MwSt.-Satz" SelectedValueBinding="{Binding MehrwertsteuersatzID}" DisplayMemberPath="Name" SelectedValuePath="ID">
             <DataGridComboBoxColumn.ElementStyle>
                 <Style TargetType="{x:Type ComboBox}">
                     <Setter Property="ItemsSource" Value="{Binding Path=DataContext.Mehrwertsteuersaetze,                         RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
                     <Setter Property="ItemStringFormat" Value="P"></Setter>
                 </Style>
             </DataGridComboBoxColumn.ElementStyle>
             <DataGridComboBoxColumn.EditingElementStyle>
                 <Style TargetType="{x:Type ComboBox}">
                     <Setter Property="ItemsSource" Value="{Binding Path=DataContext.Mehrwertsteuersaetze,                         RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
                     <Setter Property="ItemStringFormat" Value="P"></Setter>
                 </Style>
             </DataGridComboBoxColumn.EditingElementStyle>

Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.

Bitte geben Sie die Zeichenfolge in das nachfolgende Textfeld ein

Die mit einem * markierten Felder sind Pflichtfelder.

Neues aus unseren Magazinen
Listenfeld: Reihenfolge mehrerer Einträge...

Wir haben bereits in mehreren Beiträgen beschrieben, wie Sie die individuelle Reihenfolge von Elementen einer Tabelle über den Inhalt eines Feldes etwa namens »ReihenfolgeID« einstellen können –... [mehr]

Diagramme mit gefilterten Daten

In Ausgabe 2/2019 haben wir in zwei Artikeln die modernen Diagramme von Access vorgestellt. Im vorliegenen Beitrag zeigen wir Ihnen, wie Sie diese abhängig von den in einem Formular angezeigten... [mehr]

Benutzerverwaltung mit verschlüsselten...

Wenn Sie in einer Access-Anwendung Benutzer verwalten wollen, die sich per Benutzername und Kennwort an die Anwendung anmelden, sollten Sie sehr sensibel mit den in der Anwendung gespeicherten... [mehr]

HTML-Tabellen mit fester Kopfzeile

In den vorherigen Ausgaben von Access im Unternehmen und in der aktuellen Ausgabe arbeiten wir in einigen Beiträgen mit dem Webbrowser-Steuerelement und stellen Daten, die wir mit den Bordmitteln... [mehr]

Flexible HTML-Tabellen mit fester Kopfzeile

Im Beitrag »HTML-Tabellen mit fester Kopfzeile« haben wir gezeigt, wie Sie Daten aus einer bestimmten Abfrage in einem Webbrowser-Steuerelement so anzeigen, dass die Spaltenköpfe oben fixiert... [mehr]

Berechtigungen per HTML verwalten

Im Beitrag »Benutzerverwaltung mit verschlüsselten Kennwörtern« stellen wir eine Lösung vor, in der wir die Berechtigungen von Benutzergruppen an Datenbankobjekten definieren. Dort benötigen wir... [mehr]

Benutzer und Berechtigungen ermitteln

In den Beiträgen »Benutzerverwaltung mit verschlüsselten Kennwörtern« und »Berechtigungen per HTML verwalten« haben wir die Voraussetzungen für eine Benutzerverwaltung geschaffen. Im vorliegenden... [mehr]

Zugriffsrechte mit Datenmakros

Es gibt verschiedene Möglichkeiten, auf Basis des aktuell angemeldeten Benutzers sicherzustellen, dass dieser nur die für ihn vorgesehenen Aktionen mit Daten durchführen darf – beispielsweise durch... [mehr]

Kennwörter generieren

Für den einen oder anderen Zweck möchten Sie vielleicht Kennwörter generieren oder in einer Benutzeroberfläche die Möglichkeit zum Generieren von Kennwörtern anbieten. Wenn Sie etwa Benutzer zu... [mehr]

Neuer Datensatz von Frontend zu Backend

Für manche Themen gibt es keine kurze, prägnante Überschrift. In diesem Fall wollen wir zeigen, wie Sie einen neuen Datensatz anlegen, der in einer temporären Tabelle im Frontend gespeichert wird,... [mehr]