Tutorial: Erstellen einer Kundendatenbankanwendung
In diesem Tutorial wird eine einfache App zum Verwalten einer Kundenliste erstellt. Dabei wird eine Auswahl grundlegender Konzepte für Unternehmens-Apps in UWP vorgestellt. Sie lernen Folgendes:
- Implementieren Sie Erstellungs-, Lese-, Aktualisierungs- und Löschvorgänge für eine lokale SQL-Datenbank.
- Fügen Sie ein Datenraster hinzu, um Kundendaten in Ihrer Benutzeroberfläche anzuzeigen und zu bearbeiten.
- Ordnen Sie UI-Elemente in einem einfachen Formularlayout zusammen.
Der Ausgangspunkt für dieses Tutorial ist eine Einzelseiten-App mit minimaler Benutzeroberfläche und Funktionalität, basierend auf einer vereinfachten Version der Beispiel-App „Datenbank für Kundenaufträge“. Sie wird in C# und XAML geschrieben, und es wird vorausgesetzt, dass Sie mit diesen beiden Sprachen vertraut sind.
Voraussetzungen
- Vergewissern Sie sich, dass Sie über die neueste Version von Visual Studio und dem Windows SDK verfügen.
- Klonen oder Herunterladen des Beispiels aus dem Kundendatenbank-Tutorial
Nachdem Sie das Repository geklont/heruntergeladen haben, können Sie das Projekt bearbeiten, indem Sie CustomerDatabaseTutorial.sln mit Visual Studio öffnen.
Hinweis
Dieses Tutorial basiert auf dem Beispiel für eine Kundenauftragsdatenbank, das kürzlich aktualisiert wurde, um WinUI und das Windows App SDK zu verwenden. Bis dieses Tutorial und der Code aktualisiert werden, gibt es Unterschiede zwischen den beiden Beispielen.
Teil 1: Code von Interesse
Wenn Sie Ihre App unmittelbar nach dem Öffnen ausführen, werden am oberen Rand des leeren Bildschirms einige Schaltflächen angezeigt. Obwohl dies für Sie nicht sichtbar ist, enthält die App bereits eine lokale SQLite-Datenbank, die mit einigen Testkund*innen bereitgestellt wird. Von hier aus implementieren Sie zunächst ein UI-Steuerelement, um diese Kund*innen anzuzeigen, und fahren dann mit dem Hinzufügen von Vorgängen für die Datenbank fort. Bevor Sie beginnen, sehen Sie sich im Folgenden an, wo Sie arbeiten werden.
Ansichten
CustomerListPage.xaml ist die Ansicht der App, die die Benutzeroberfläche der einzelnen Seite in diesem Tutorial definiert. Jedes Mal, wenn Sie ein visuelles Element in der Benutzeroberfläche hinzufügen oder ändern müssen, tun Sie es in dieser Datei. In diesem Tutorial werden Sie durch das Hinzufügen der folgenden Elemente geführt:
- Eines RadDataGrid zum Anzeigen und Bearbeiten Ihrer Kund*innen.
- Eines StackPanel zum Festlegen der Anfangswerte für neue Kund*innen.
ViewModels
ViewModels\CustomerListPageViewModel.cs ist der Ort, an dem sich die grundlegende Logik der App befindet. Jede In der Ansicht ausgeführte Benutzeraktion wird zur Verarbeitung an diese Datei übergeben. In diesem Tutorial fügen Sie neuen Code hinzu und implementieren die folgenden Methoden:
- CreateNewCustomerAsync, das ein neues CustomerViewModel-Objekt initialisiert.
- DeleteNewCustomerAsync, das eine*n neue*n Kund*in entfernt, bevor er/sie in der Benutzeroberfläche angezeigt wird.
- DeleteAndUpdateAsync, das die Logik der Schaltfläche „Löschen“ behandelt.
- GetCustomerListAsync, das eine Liste von Kund*innen aus der Datenbank abruft.
- SaveInitialChangesAsync, das der Datenbank Informationen eines/einer neuen Kund*in hinzufügt.
- UpdateCustomersAsync, das die Benutzeroberfläche aktualisiert, um alle hinzugefügten oder gelöschten Kund*innen widerzuspiegeln.
CustomerViewModel ist ein Wrapper für Kundeninformationen, der verfolgt, ob sie kürzlich geändert wurden. Sie müssen dieser Klasse nichts hinzufügen, aber ein Teil des Codes, den Sie an anderer Stelle hinzufügen, verweist darauf.
Weitere Informationen zum Erstellen des Beispiels finden Sie in der Übersicht über die App-Struktur.
Teil 2: Hinzufügen des DataGrid
Bevor Sie mit der Arbeit mit Kundendaten beginnen, müssen Sie ein UI-Steuerelement hinzufügen, um diese Kund*innen anzuzeigen. Dazu verwenden wir ein vordefiniertes RadDataGrid-Steuerelement eines Drittanbieters. Das Telerik.UI.for.UniversalWindowsPlatform NuGet-Paket ist bereits in diesem Projekt enthalten. Wir fügen das Raster nun unserem Projekt hinzu.
Öffnen Sie Views\CustomerListPage.xaml aus dem Projektmappen-Explorer. Fügen Sie die folgende Codezeile innerhalb des Page-Tags hinzu, um eine Zuordnung zum Telerik-Namespace zu deklarieren, der das Datenraster enthält.
xmlns:telerikGrid="using:Telerik.UI.Xaml.Controls.Grid"
Fügen Sie unterhalb der CommandBar im Haupt-RelativePanel der Ansicht ein RadDataGrid-Steuerelement mit einigen grundlegenden Konfigurationsoptionen hinzu:
<Grid x:Name="CustomerListRoot" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <RelativePanel> <CommandBar x:Name="mainCommandBar" HorizontalAlignment="Stretch" Background="AliceBlue"> <!--CommandBar content--> </CommandBar> <telerikGrid:RadDataGrid x:Name="DataGrid" BorderThickness="0" ColumnDataOperationsMode="Flyout" GridLinesVisibility="None" GroupPanelPosition="Left" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True" RelativePanel.Below="mainCommandBar" /> </RelativePanel> </Grid>
Sie haben das Datenraster hinzugefügt, es benötigt jedoch Daten zum Anzeigen. Fügen Sie die folgenden Codezeilen hinzu:
ItemsSource="{x:Bind ViewModel.Customers}" UserEditMode="Inline"
Nachdem Sie nun eine anzuzeigende Datenquelle definiert haben, verarbeitet RadDataGrid den größten Teil der UI-Logik für Sie. Wenn Sie ihr Projekt ausführen, werden jedoch weiterhin keine Daten angezeigt. Das liegt daran, dass das ViewModel die Daten noch nicht lädt.
Teil 3: Kundendaten lesen
Bei der Initialisierung ruft ViewModels\CustomerListPageViewModel.cs die GetCustomerListAsync-Methode auf. Diese Methode muss die Testkundendaten aus der SQLite-Datenbank abrufen, die im Tutorial enthalten ist.
Aktualisieren Sie in ViewModels\CustomerListPageViewModel.cs Ihre GetCustomerListAsync-Methode mit diesem Code:
public async Task GetCustomerListAsync() { var customers = await App.Repository.Customers.GetAsync(); if (customers == null) { return; } await DispatcherHelper.ExecuteOnUIThreadAsync(() => { Customers.Clear(); foreach (var c in customers) { Customers.Add(new CustomerViewModel(c)); } }); }
Die GetCustomerListAsync-Methode wird aufgerufen, wenn das ViewModel geladen wird, aber vor diesem Schritt wurde nichts ausgeführt. Hier haben wir einen Aufruf der GetAsync-Methode in Repository/SqlCustomerRepository hinzugefügt. Auf diese Weise kann das Repository kontaktiert werden, um eine aufzählbare Sammlung von Kundenobjekten abzurufen. Anschließend werden sie in einzelne Objekte zerlegt, bevor sie zu ihrer internen ObservableCollection hinzugefügt werden, damit sie angezeigt und bearbeitet werden können.
Führen Sie Ihre App aus. Nun zeigt das Datenraster die Kundenliste an.
Teil 4: Kundendaten bearbeiten
Sie können die Einträge im Datenraster bearbeiten, indem Sie darauf doppelklicken. Sie müssen jedoch sicherstellen, dass alle Änderungen, die Sie in der Benutzeroberfläche vornehmen, auch an Ihrer Kundensammlung im CodeBehind vorgenommen werden. Dies bedeutet, dass Sie die bidirektionale Datenbindung implementieren müssen. Weitere Informationen hierzu finden Sie in unserer Einführung in die Datenbindung.
Deklarieren Sie zunächst, dass ViewModels\CustomerListPageViewModel.cs die INotifyPropertyChanged-Schnittstelle implementiert:
public class CustomerListPageViewModel : INotifyPropertyChanged
Fügen Sie dann im Hauptteil der Klasse das folgende Ereignis und die folgende Methode hinzu:
public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
Die OnPropertyChanged-Methode erleichtert es den Settern, das PropertyChanged-Ereignis auszulösen, das für die bidirektionale Datenbindung erforderlich ist.
Aktualisieren Sie den Setter für SelectedCustomer mit diesem Funktionsaufruf:
public CustomerViewModel SelectedCustomer { get => _selectedCustomer; set { if (_selectedCustomer != value) { _selectedCustomer = value; OnPropertyChanged(); } } }
Fügen Sie in Views\CustomerListPage.xaml die SelectedCustomer-Eigenschaft zu Ihrem Datenraster hinzu.
SelectedItem="{x:Bind ViewModel.SelectedCustomer, Mode=TwoWay}"
Dadurch wird die Benutzerauswahl im Datenraster mit dem entsprechenden Kundenobjekt im CodeBehind verknüpft. Der TwoWay-Bindungsmodus ermöglicht es, die Änderungen, die in der Benutzeroberfläche vorgenommen wurden, für dieses Objekt widerzuspiegeln.
Führen Sie die App aus. Sie können jetzt die Im Raster angezeigten Kund*innen sehen und Änderungen an den zugrunde liegenden Daten über die Benutzeroberfläche vornehmen.
Teil 5: Kundendaten aktualisieren
Nachdem Sie Ihre Kundendaten nun sehen und bearbeiten können, müssen Sie ihre Änderungen an die Datenbank übertragen und alle Aktualisierungen abrufen können, die von anderen Personen vorgenommen wurden.
Kehren Sie zu ViewModels\CustomerListPageViewModel.cs zurück, und navigieren Sie zur UpdateCustomersAsync-Methode. Aktualisieren Sie sie mit diesem Code, um Änderungen an die Datenbank zu übertragen und neue Informationen abzurufen:
public async Task UpdateCustomersAsync() { foreach (var modifiedCustomer in Customers .Where(x => x.IsModified).Select(x => x.Model)) { await App.Repository.Customers.UpsertAsync(modifiedCustomer); } await GetCustomerListAsync(); }
Dieser Code verwendet die IsModified-Eigenschaft von ViewModels\CustomerViewModel.cs, die bei jeder Änderung der Kundendaten automatisch aktualisiert wird. Auf diese Weise können Sie unnötige Aufrufe vermeiden und nur Änderungen von aktualisierten Kund*innen an die Datenbank übertragen.
Teil 6: Eine*n neue*n Kund*in erstellen
Das Hinzufügen neuer Kund*innen stellt eine Herausforderung dar, da der/die Kund*in als leere Zeile angezeigt wird, wenn Sie ihn/sie der Benutzeroberfläche hinzufügen, bevor Sie Werte für seine/ihre Eigenschaften angeben. Das ist kein Problem, aber wir wollen das Festlegen der Anfangswerte für Kund*innen erleichtern. In diesem Tutorial fügen wir einen einfachen reduzierbaren Bereich hinzu, aber wenn Sie weitere Informationen zum Hinzufügen hatten, könnten Sie zu diesem Zweck eine separate Seite erstellen.
Aktualisieren der CodeBehind-Datei
Fügen Sie ein neues privates Feld und eine öffentliche Eigenschaft zu ViewModels\CustomerListPageViewModel.cs hinzu. Dies wird verwendet, um zu steuern, ob das Panel sichtbar ist.
private bool _addingNewCustomer = false; public bool AddingNewCustomer { get => _addingNewCustomer; set { if (_addingNewCustomer != value) { _addingNewCustomer = value; OnPropertyChanged(); } } }
Fügen Sie dem ViewModel eine neue öffentliche Eigenschaft hinzu, eine Umkehrung des Werts von AddingNewCustomer. Dies wird verwendet, um die regulären Befehlsleistenschaltflächen zu deaktivieren, wenn der Bereich sichtbar ist.
public bool EnableCommandBar => !AddingNewCustomer;
Sie benötigen nun eine Möglichkeit zum Anzeigen des reduzierbaren Bereichs und zum Erstellen eines/einer Kund*in für die Bearbeitung.
Fügen Sie dem ViewModel für den/die neu erstellte*n Kund*in eine neue private und öffentliche Eigenschaft hinzu.
private CustomerViewModel _newCustomer; public CustomerViewModel NewCustomer { get => _newCustomer; set { if (_newCustomer != value) { _newCustomer = value; OnPropertyChanged(); } } }
Aktualisieren Sie Ihre CreateNewCustomerAsync-Methode, um eine*n neue*n Kund*in zu erstellen, dem Repository hinzuzufügen und als ausgewählte*n Kund*in festzulegen:
public async Task CreateNewCustomerAsync() { CustomerViewModel newCustomer = new CustomerViewModel(new Models.Customer()); NewCustomer = newCustomer; await App.Repository.Customers.UpsertAsync(NewCustomer.Model); AddingNewCustomer = true; }
Aktualisieren Sie die SaveInitialChangesAsync-Methode, um dem Repository eine*n neu erstellte*n Kund*in hinzuzufügen, die Benutzeroberfläche zu aktualisieren und den Bereich zu schließen.
public async Task SaveInitialChangesAsync() { await App.Repository.Customers.UpsertAsync(NewCustomer.Model); await UpdateCustomersAsync(); AddingNewCustomer = false; }
Fügen Sie die folgende Codezeile als letzte Zeile im Setter für AddingNewCustomer hinzu:
OnPropertyChanged(nameof(EnableCommandBar));
Dadurch wird sichergestellt, dass EnableCommandBar bei jeder Änderung von AddingNewCustomer automatisch aktualisiert wird.
Aktualisieren der Benutzeroberfläche
Navigieren Sie zurück zu Views\CustomerListPage.xaml, und fügen Sie ein StackPanel mit den folgenden Eigenschaften zwischen dem CommandBar-Element und Ihrem Datenraster hinzu:
<StackPanel x:Name="newCustomerPanel" Orientation="Horizontal" x:Load="{x:Bind ViewModel.AddingNewCustomer, Mode=OneWay}" RelativePanel.Below="mainCommandBar"> </StackPanel>
Das x:Load-Attribut stellt sicher, dass dieser Bereich nur beim Hinzufügen neuer Kund*innen angezeigt wird.
Nehmen Sie die folgende Änderung an der Position des Datenrasters vor, um sicherzustellen, dass es nach unten verschoben wird, wenn der neue Bereich angezeigt wird:
RelativePanel.Below="newCustomerPanel"
Aktualisieren Sie den Stapelbereich mit vier TextBox-Steuerelementen. Sie binden an die einzelnen Eigenschaften des/der neuen Kund*in und ermöglichen es Ihnen, die Werte zu bearbeiten, bevor Sie sie zum Datenraster hinzufügen.
<StackPanel x:Name="newCustomerPanel" Orientation="Horizontal" x:Load="{x:Bind ViewModel.AddingNewCustomer, Mode=OneWay}" RelativePanel.Below="mainCommandBar"> <TextBox Header="First name" PlaceholderText="First" Margin="8,8,16,8" MinWidth="120" Text="{x:Bind ViewModel.NewCustomer.FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> <TextBox Header="Last name" PlaceholderText="Last" Margin="0,8,16,8" MinWidth="120" Text="{x:Bind ViewModel.NewCustomer.LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> <TextBox Header="Address" PlaceholderText="1234 Address St, Redmond WA 00000" Margin="0,8,16,8" MinWidth="280" Text="{x:Bind ViewModel.NewCustomer.Address, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> <TextBox Header="Company" PlaceholderText="Company" Margin="0,8,16,8" MinWidth="120" Text="{x:Bind ViewModel.NewCustomer.Company, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> </StackPanel>
Fügen Sie ihrem neuen Stapelbereich eine einfache Schaltfläche hinzu, um den/die neu erstellte*n Kund*in zu speichern:
<StackPanel> <!--Text boxes from step 3--> <AppBarButton x:Name="SaveNewCustomer" Click="{x:Bind ViewModel.SaveInitialChangesAsync}" Icon="Save"/> </StackPanel>
Aktualisieren Sie die CommandBar, sodass die normalen Schaltflächen für Erstellen, Löschen und Aktualisieren deaktiviert sind, wenn der Stapelbereich sichtbar ist:
<CommandBar x:Name="mainCommandBar" HorizontalAlignment="Stretch" IsEnabled="{x:Bind ViewModel.EnableCommandBar, Mode=OneWay}" Background="AliceBlue"> <!--App bar buttons--> </CommandBar>
Führen Sie die App aus. Sie können jetzt eine*n Kund*in erstellen und die Daten im Stapelbereich eingeben.
Teil 7: Löschen eines/einer Kund*in
Das Löschen eines/einer Kund*in ist der letzte grundlegende Vorgang, den Sie implementieren müssen. Wenn Sie eine*n Kund*in löschen, den/die Sie im Datenraster ausgewählt haben, sollte UpdateCustomersAsync sofort aufgerufen werden, um die Benutzeroberfläche zu aktualisieren. Sie müssen diese Methode jedoch nicht aufrufen, wenn Sie eine*n Kund*in löschen, den/die Sie gerade erstellt haben.
Navigieren Sie zu ViewModels\CustomerListPageViewModel.cs, und aktualisieren Sie die DeleteAndUpdateAsync-Methode:
public async void DeleteAndUpdateAsync() { if (SelectedCustomer != null) { await App.Repository.Customers.DeleteAsync(_selectedCustomer.Model.Id); } await UpdateCustomersAsync(); }
Aktualisieren Sie in Views\CustomerListPage.xaml den Stapelbereich zum Hinzufügen neuer Kund*innen, sodass er eine zweite Schaltfläche enthält:
<StackPanel> <!--Text boxes for adding a new customer--> <AppBarButton x:Name="DeleteNewCustomer" Click="{x:Bind ViewModel.DeleteNewCustomerAsync}" Icon="Cancel"/> <AppBarButton x:Name="SaveNewCustomer" Click="{x:Bind ViewModel.SaveInitialChangesAsync}" Icon="Save"/> </StackPanel>
Aktualisieren Sie in ViewModels\CustomerListPageViewModel.cs die DeleteNewCustomerAsync-Methode, um den/die neue*n Kund*in zu löschen:
public async Task DeleteNewCustomerAsync() { if (NewCustomer != null) { await App.Repository.Customers.DeleteAsync(_newCustomer.Model.Id); AddingNewCustomer = false; } }
Führen Sie die App aus. Sie können Kund*innen jetzt entweder im Datenraster oder im Stapelbereich löschen.
Zusammenfassung
Herzlichen Glückwunsch! Damit verfügt Ihre App jetzt über einen vollständigen Bereich lokaler Datenbankvorgänge. Sie können Kund*innen in Ihrer Benutzeroberfläche erstellen, lesen, aktualisieren und löschen, und diese Änderungen werden in Ihrer Datenbank gespeichert und bleiben bei verschiedenen Starts Ihrer App erhalten.
Nachdem Sie fertig sind, ziehen Sie Folgendes in Betracht:
- Falls Sie es noch nicht getan haben, sehen Sie sich die Übersicht über die App-Struktur an, um zu erfahren, warum die App auf diese Weise aufgebaut ist.
- Erkunden Sie das vollständige Beispiel für die Kundenauftragsdatenbank, um die App zu sehen, auf der dieses Tutorial basiert.
Oder, wenn Sie für eine Herausforderung bereit sind, können Sie fortfahren …
Vertiefung: Verbinden zu einer Remotedatenbank
Wir haben eine Schritt-für-Schritt-Anleitung zur Implementierung dieser Aufrufe für eine lokale SQLite-Datenbank bereitgestellt. Aber was ist, wenn Sie stattdessen eine Remotedatenbank verwenden möchten?
Wenn Sie dies ausprobieren möchten, benötigen Sie Ihr eigenes Azure Active Directory (AAD)-Konto und die Fähigkeit, Ihre eigene Datenquelle zu hosten.
Sie müssen eine Authentifizierung sowie Funktionen zum Verarbeiten von REST-Aufrufen hinzufügen und dann eine Remotedatenbank für die Interaktion erstellen. Im vollständigen Beispiel für die Kundenauftragsdatenbank gibt es Code, den Sie für jeden erforderlichen Vorgang als Referenz heranziehen können.
Einstellungen und Konfiguration
Die erforderlichen Schritte zum Herstellen einer Verbindung mit Ihrer eigenen Remotedatenbank werden in der Infodatei des Beispiels beschrieben. Sie müssen wie folgt vorgehen:
- Stellen Sie Constants.cs Ihre Azure-Konto-Client-ID bereit.
- Stellen Sie Constants.cs die URL der Remotedatenbank bereit.
- Stellen Sie Constants.cs die Verbindungszeichenfolge für die Datenbank bereit.
- Ordnen Sie Ihre App dem Microsoft Store zu.
- Kopieren Sie das Dienstprojekt in Ihre App, und stellen Sie es in Azure bereit.
Authentifizierung
Sie müssen eine Schaltfläche erstellen, um eine Authentifizierungssequenz zu starten, und ein Popup oder eine separate Seite, um Benutzerinformationen zu sammeln. Nachdem Sie dies erstellt haben, müssen Sie Code bereitstellen, der die Benutzerinformationen anfordert und zum Abrufen eines Zugriffstokens verwendet. Im Beispiel für die Kundenauftragsdatenbank werden Microsoft Graph-Aufrufe mit der WebAccountManager-Bibliothek umschlossen, um ein Token abzurufen und die Authentifizierung für ein AAD-Konto zu verarbeiten.
- Die Authentifizierungslogik wird in AuthenticationViewModel.cs implementiert.
- Der Authentifizierungsprozess wird im benutzerdefinierten AuthenticationControl.xaml-Steuerelement angezeigt.
REST-Aufrufe
Sie müssen keinen Code ändern, den wir in diesem Tutorial hinzugefügt haben, um REST-Aufrufe zu implementieren. Stattdessen müssen Sie Folgendes tun:
- Erstellen Sie neue Implementierungen der ICustomerRepository- und ITutorialRepository-Schnittstellen, die denselben Satz von Funktionen über REST anstelle von SQLite implementieren. Sie müssen JSON serialisieren und deserialisieren und können ihre REST-Aufrufe in einer separaten HttpHelper-Klasse umschließen, falls erforderlich. Weitere Informationen finden Sie im vollständigen Beispiel.
- Erstellen Sie in App.xaml.cs eine neue Funktion zum Initialisieren des REST-Repositorys, und rufen Sie es anstelle von SqliteDatabase auf, wenn die App initialisiert wird. Auch hierzu finden Sie weitere Informationen im vollständigen Beispiel.
Sobald alle drei dieser Schritte abgeschlossen sind, sollten Sie sich über Ihre App bei Ihrem AAD-Konto authentifizieren können. REST-Aufrufe an die Remotedatenbank ersetzen die lokalen SQLite-Aufrufe, die Benutzeroberfläche sollte jedoch identisch sein. Wenn Sie besonders ambitioniert sind, können Sie eine Einstellungsseite hinzufügen, sodass Benutzer*innen dynamisch zwischen den beiden wechseln können.