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.
Adressen verwalten
Für unsere Lösung zum Erstellen und Verwalten von Word-Dokumenten aus dem Artikel »Briefe mit Word erstellen« benötigen wir eine Möglichkeit zum Anlegen und Verwalten von Adressen. Dazu wollen wir ein eigenes Fenster erstellen, dass eine Übersicht der Adressen in einer Liste, eine kleine Suchfunktion sowie die Details der aktuell in der Liste ausgewählten Adresse oder einer neuen Adresse anzeigt. Die Lösung soll natürlich über ein Entity Data Model an eine entsprechende Tabelle gebunden werden.
Zur Anzeige der Adressen fügen wir der Lösung ein neues Fenster namens Adressen.xaml hinzu. Für die Anordnung der benötigten Steuerelemente wollen wir dem Grid ein Raster von vier Spalten und acht Zeilen hinzufügen. Die erste und die dritte Spalte weisen als Spaltenbreite den Wert Auto auf, damit sich die Breite an den breitesten enthaltenen Steuerelementen orientiert, in diesem Fall an den Inhalten der Label-Elemente mit den Feldbeschriftungen. Die zweite und die vierte Spalte sollen sich den Rest der Breite aufteilen, damit der Benutzer das Fenster verbreitern und somit Inhalte der Textfelder, die gegebenenfalls nicht vollständig angezeigt werden, sichtbar machen kann.
Die Zeilen werden mit einer Ausnahme alle mit der Zeilenhöhe Auto ausgestattet, damit sich diese an der für die enthaltenen Elemente notwendigen Höhe orientieren können. Die Ausnahme ist die zweite Zeile, welche das Listenfeld zur Anzeige der Adressen in der Übersicht anzeigen soll. Diese Zeile erhält für die Eigenschaft Height den Wert *, was dazu führt, dass sie den verbleibenden Platz einnimmt und beim Vergrößern der Höhe des Fensters ebenfalls vergrößert wird. Die Definition des Grundgerüsts des Fensters mit XAML-Code sieht wie folgt aus und erscheint im Entwurf wie in Bild 1:
Bild 1: Fenster zum Verwalten von Adressen
<Window x:Class="Adressen" ... Title="Adressen" Height="350" Width="400">
<Window.Resources>
<Style TargetType="TextBox">
<Setter Property="Margin" Value="3"></Setter>
<Setter Property="Padding" Value="3"></Setter>
</Style>
...
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
...
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label>Suche:</Label>
<Label Grid.Row="2">Firma:</Label>
<Label Grid.Row="3">Anrede:</Label>
... weitere Label
<Label Grid.Row="2" Grid.Column="2">PLZ:</Label>
<Label Grid.Row="3" Grid.Column="2">Ort:</Label>
... weitere Label
<TextBox x:Name="txtSuchbegriff" Grid.Column="1" Grid.ColumnSpan="3"></TextBox>
<ListBox x:Name="lstAdressen" Grid.Row="1" Grid.ColumnSpan="4" Margin="3" Padding="3"></ListBox>
<TextBox x:Name="txtFirma" Grid.Row="2" Grid.Column="1"></TextBox>
<ComboBox x:Name="cboAnreden" Grid.Row="3" Grid.Column="1"></ComboBox>
<TextBox x:Name="txtVorname" Grid.Row="4" Grid.Column="1"></TextBox>
... weitere TextBox-Elemente
<StackPanel Orientation="Horizontal" Grid.Row="7" Grid.ColumnSpan="4">
<Button x:Name="btnOK">OK</Button>
<Button x:Name="btnSpeichern">Speichern</Button>
<Button x:Name="btnNeu">Neue Adresse</Button>
<Button x:Name="btnLoeschen">Adresse löschen</Button>
</StackPanel>
</Grid>
</Window>
Im unteren Bereich findet sich noch ein StackPanel, welches ebenfalls über die gesamten vier Spalten geht und in horizontaler Ausrichtung vier Button-Elemente anzeigt. Für die Steuerelementtypen Label, TextBox, ListBox, ComboBox und Button haben wir im oberen Bereich unter Window.Resources einige allgemeine Eigenschaften wie Margin und Padding festgelegt. Diese greifen bei den Steuerelementen, die per ColumnSpan über mehrere Spalten angelegt werden, nicht – daher müssen wir zum Beispiel die Eigenschaft Margin für das Textfeld zur Eingabe des Suchbegriffs und das Listenfeld direkt mit dem Steuerelement definieren.
Entity Data Model
Das Entity Data Model für die Lösung haben wir bereits im Beitrag EDM: Die Code First-Methode und EDM: Code First - Datenbank erweitern besprochen. Der Teil, der für die hier zu verwaltenden Adressen verantwortlich ist, sind die beiden Klassen Adresse und Anrede. Wir benötigen für das Listenfeld eine Auflistung der Adressen mit den wichtigsten Feldern, für das Kombinationsfeld cboAnreden eine Auflistung der Anreden und für die Details der aktuell bearbeiteten Adresse ein Objekt auf Basis der Klasse Adresse. Um die Steuerelemente des Fensters an die Daten der beiden Klassen zu binden, fügen wir zunächst eine öffentliche Eigenschaft für ein Objekt auf Basis der Klasse Adresse zur Code behind-Klasse hinzu:
Public Property AktuelleAdresse As Adresse
Außerdem benötigen wir eine Variable zum Speichern der Objektvariablen für das DbContext-Element:
Private WordbriefContext As WordbriefEntities
Für die Liste der Adressen im ListView-Steuerelement sehen wir die folgende Variable vor:
Public Property Adressenliste As ObservableCollection(Of Adresse)
Fehlt noch eine Collection für die Anreden, die wir so deklarieren:
Public Property Anredenliste As ObservableCollection(Of Anrede)
Dann erstellen wir das Grundgerüst für die Konstruktor-Methode, also die Methode, die beim Öffnen des Fensters ausgelöst wird. Nun können wir das Fenster auf zwei Arten öffnen: Erstens mit der Schaltfläche zum Bearbeiten des aktuell im Hauptfenster MainWindow.xaml angezeigten Datensatzes und zweitens mit der Schaltfläche zum Erstellen eines neuen Adress-Objekts. Das heißt also, dass wir entweder eine ID aus dem aufrufenden Fenster übergeben müssen oder, wenn ein neues Element angelegt werden soll, eben nicht. Das ist eine gute Gelegenheit, einmal das Überladen der Konstruktor-Methode zu demonstrieren. Das bedeutet, dass wir zwei verschiedene Konstruktor-Methoden erstellen, von denen die eine keinen Parameter enthält – das ist die zum Anlegen eines neuen Elements. Die andere soll einen bestehenden Adress-Datensatz anzeigen, also übergeben wir dieser Konstruktor-Methode die ID des anzuzeigenden Datensatzes.
Dazu legen wir einen entsprechenden Parameter an. Grundsätzlich sehen die beiden Methoden also wie folgt aus:
Public Sub New()
InitializeComponent()
...
End Sub
Public Sub New(AdresseID As Integer)
InitializeComponent()
...
End Sub
Sie brauchen übrigens immer nur den Kopf mit Public Sub New(...) einzugeben, Visual Studio erzeugt dann immer den Rest mit der Anweisung InitializeComponent und den üblichen Kommentarzeilen – das gilt auch, wenn Sie Überladungen der New-Methode angeben.
Konstruktor-Methoden füllen
Damit begeben wir uns an die Konstruktor-Methoden. Die Methode New ohne Parameter soll dafür sorgen, dass das Fenster AdressenVerwalten.xaml einen neuen, leeren Datensatz anzeigt, den der Benutzer dann mit Daten füllen und speichern kann. Dazu benötigen wir die folgende Konstruktor-Methode:
Public Sub New()
InitializeComponent()
WordbriefContext = New WordbriefEntities
Adressenliste = New ObservableCollection(Of Adresse)(WordbriefContext.Adressen)
AktuelleAdresse = New Adresse
Anredenliste = New ObservableCollection(Of Anrede)(WordbriefContext.Anreden)
DataContext = Me
End Sub
Die Methode füllt WordbriefContext mit dem Entity Data Model. Außerdem liest sie die Adressen und Anreden in die Collections Adressen und Anreden ein. Die Variable Adresse wird einem neuen Element des Typs Adresse gefüllt. Die zweite Konstruktor-Methode erwartet den Parameter SelektierteAdresse des Typs Adresse, der vom aufrufenden Fenster übergeben wird und in den Steuerelementen des Fensters AdressenVerwalten als aktive Adresse angezeigt werden soll:
Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.