Tutoriel : Créer une application de base de données de clients
Ce didacticiel crée une application simple pour gérer une liste de clients. Ce faisant, il présente une sélection de concepts de base pour les applications d'entreprise dans UWP. Vous découvrirez comment effectuer les actions suivantes :
- Mettez en œuvre des opérations de création, de lecture, de mise à jour et de suppression sur une base de données SQL locale.
- Ajouter une grille de données pour afficher et modifier les données des clients dans votre interface utilisateur.
- Disposer les éléments de l'interface utilisateur dans un formulaire de base.
Le point de départ de ce tutoriel est une application d'une seule page avec une interface utilisateur et des fonctions minimales, basée sur une version simplifiée de l'exemple d'application Base de données des commandes clients. Elle est écrite en C# et en XAML, et nous nous attendons à ce que vous ayez une connaissance de base de ces deux langages.
Prérequis
- Assurez-vous que vous disposez de la dernière version de Visual Studio et du SDK Windows
- Clonez ou téléchargez l'exemple du didacticiel sur la base de données clients
Après avoir cloné/téléchargé le référentiel, vous pouvez éditer le projet en ouvrant CustomerDatabaseTutorial.sln avec Visual Studio.
Remarque
Ce tutoriel est basé sur l'exemple de base de données des commandes clients qui a été récemment mis à jour pour utiliser WinUI et le SDK d'application Windows. Jusqu'à ce que ce tutoriel et le code soient mis à jour, il y aura des différences entre les deux exemples.
Partie 1 : Code d'intérêt
Si vous exécutez votre application immédiatement après l'avoir ouverte, vous verrez quelques boutons en haut d'un écran vide. Bien qu'elle ne soit pas visible pour vous, l'application comprend déjà une base de données SQLite locale approvisionnée avec quelques clients de test. À partir de là, vous commencerez par implémenter un contrôle d'interface utilisateur pour afficher ces clients, puis vous passerez à l'ajout d'opérations sur la base de données. Avant de commencer, voici où vous allez travailler.
Vues
CustomerListPage.xaml est la vue de l'application, qui définit l'interface utilisateur de la page unique de ce tutoriel. Chaque fois que vous devrez ajouter ou modifier un élément visuel de l'interface utilisateur, vous le ferez dans ce fichier. Ce didacticiel vous guidera dans l'ajout de ces éléments :
- Une grille RadDataGrid pour afficher et modifier vos clients.
- Un StackPanel pour définir les valeurs initiales d'un nouveau client.
ViewModels
ViewModels\CustomerListPageViewModel.cs est l'endroit où se trouve la logique fondamentale de l'application. Chaque action de l'utilisateur effectuée dans la vue sera transmise à ce fichier pour être traitée. Dans ce tutoriel, vous ajouterez du nouveau code et mettrez en œuvre les méthodes suivantes :
- CreateNewCustomerAsync, qui initialise un nouvel objet CustomerViewModel.
- DeleteNewCustomerAsync, qui supprime un nouveau client avant qu'il ne soit affiché dans l'interface utilisateur.
- DeleteAndUpdateAsync, qui gère la logique du bouton de suppression.
- GetCustomerListAsync, qui récupère une liste de clients dans la base de données.
- SaveInitialChangesAsync, qui ajoute les informations d'un nouveau client à la base de données.
- UpdateCustomersAsync, qui actualise l'interface utilisateur en fonction des clients ajoutés ou supprimés.
CustomerViewModel est un wrapper pour les informations d'un client, qui permet de savoir si elles ont été récemment modifiées ou non. Vous n'aurez pas besoin d'ajouter quoi que ce soit à cette classe, mais une partie du code que vous ajouterez ailleurs y fera référence.
Pour plus d'informations sur la construction de l'exemple, consultez l'aperçu de la structure de l'application.
Partie 2 : Ajouter la grille de données
Avant de commencer à exploiter les données des clients, vous devez ajouter un contrôle d'interface utilisateur pour afficher ces clients. Pour ce faire, nous utiliserons un contrôle RadDataGrid tiers prédéfini. Le package NuGet Telerik.UI.for.UniversalWindowsPlatform a déjà été inclus dans ce projet. Ajoutons la grille à notre projet.
Ouvrez Views\CustomerListPage.xaml dans l'explorateur de solutions. Ajoutez la ligne de code suivante dans la balise Page pour déclarer un mappage vers l'espace de noms Telerik contenant la grille de données.
xmlns:telerikGrid="using:Telerik.UI.Xaml.Controls.Grid"
Sous la CommandBar dans le RelativePanel principal de la vue, ajoutez un contrôle RadDataGrid, avec quelques options de configuration de base :
<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>
Vous avez ajouté la grille de données, mais elle a besoin de données pour s'afficher. Ajoutez-lui les lignes de code suivantes :
ItemsSource="{x:Bind ViewModel.Customers}" UserEditMode="Inline"
Maintenant que vous avez défini une source de données à afficher, RadDataGrid va gérer la plupart de la logique de l'interface utilisateur pour vous. Cependant, si vous exécutez votre projet, vous ne verrez toujours pas de données s'afficher. C'est parce que le ViewModel ne les a pas encore chargées.
Partie 3 : Lire les clients
Lorsqu'il est initialisé, ViewModels\CustomerListPageViewModel.cs appelle la méthode GetCustomerListAsync. Cette méthode doit récupérer les données des clients de test dans la base de données SQLite incluse dans le didacticiel.
Dans ViewModels\CustomerListPageViewModel.cs, mettez à jour votre méthode GetCustomerListAsync avec ce 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)); } }); }
La méthode GetCustomerListAsync est appelée lorsque le ViewModel est chargé, mais avant cette étape, elle ne faisait rien. Ici, nous avons ajouté un appel à la méthode GetAsync dans Repository/SqlCustomerRepository. Cela lui permet de contacter le référentiel pour récupérer une collection énumérable d'objets Client. Il les analyse ensuite en objets individuels, avant de les ajouter à sa collection interne ObservableCollection afin qu'ils puissent être affichés et modifiés.
Exécutez votre application - vous verrez maintenant la grille de données afficher la liste des clients.
Partie 4 : Modifier les clients
Vous pouvez modifier les entrées de la grille de données en double-cliquant dessus, mais vous devez vous assurer que toutes les modifications apportées à l'interface utilisateur sont également apportées à votre collection de clients dans le code-behind. Cela signifie que vous devrez mettre en œuvre une liaison de données bidirectionnelle. Si vous souhaitez obtenir plus d'informations à ce sujet, consultez notre introduction à la liaison de données.
Tout d'abord, déclarez que ViewModels\CustomerListPageViewModel.cs implémente l'interface INotifyPropertyChanged :
public class CustomerListPageViewModel : INotifyPropertyChanged
Ensuite, dans le corps principal de la classe, ajoutez l'événement et la méthode suivants :
public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
La méthode OnPropertyChanged permet à vos setters de déclencher facilement l'événement PropertyChanged, nécessaire à la liaison bidirectionnelle des données.
Mettez à jour le setter de SelectedCustomer avec cet appel de fonction :
public CustomerViewModel SelectedCustomer { get => _selectedCustomer; set { if (_selectedCustomer != value) { _selectedCustomer = value; OnPropertyChanged(); } } }
Dans Views\CustomerListPage.xaml, ajoutez la propriété SelectedCustomer à votre grille de données.
SelectedItem="{x:Bind ViewModel.SelectedCustomer, Mode=TwoWay}"
Cela permet d'associer la sélection de l'utilisateur dans la grille de données à l'objet Client correspondant dans le code-behind. Le mode de liaison bidirectionnel permet de répercuter sur cet objet les modifications apportées dans l'interface utilisateur.
Lancez votre application. Vous pouvez maintenant voir les clients affichés dans la grille et apporter des modifications aux données sous-jacentes par l'intermédiaire de votre interface utilisateur.
Partie 5 : Mise à jour des clients
Maintenant que vous pouvez voir et modifier vos clients, vous devez être en mesure de pousser vos modifications dans la base de données et de récupérer les mises à jour effectuées par d'autres.
Retournez à ViewModels\CustomerListPageViewModel.cs, et naviguez jusqu'à la méthode UpdateCustomersAsync. Mettez-la à jour avec ce code, afin de pousser les modifications vers la base de données et de récupérer toute nouvelle information :
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(); }
Ce code utilise la propriété IsModified de ViewModels\CustomerViewModel.cs, qui est automatiquement mise à jour chaque fois que le client est modifié. Cela vous permet d'éviter les appels inutiles et de ne pousser vers la base de données que les modifications apportées par les clients mis à jour.
Partie 6 : Créer un nouveau client
L'ajout d'un nouveau client présente un défi, car le client apparaîtra comme une ligne vide si vous l'ajoutez à l'interface utilisateur avant d'avoir fourni des valeurs pour ses propriétés. Ce n'est pas un problème, mais nous allons faciliter la définition des valeurs initiales d'un client. Dans ce tutoriel, nous ajouterons un simple panneau pliable, mais si vous aviez plus d'informations à ajouter, vous pourriez créer une page séparée à cet effet.
Mettez à jour le code-behind
Ajoutez un nouveau champ privé et une propriété publique à ViewModels\CustomerListPageViewModel.cs. Ils seront utilisés pour contrôler si le panneau est visible ou non.
private bool _addingNewCustomer = false; public bool AddingNewCustomer { get => _addingNewCustomer; set { if (_addingNewCustomer != value) { _addingNewCustomer = value; OnPropertyChanged(); } } }
Ajoutez une nouvelle propriété publique au ViewModel, l'inverse de la valeur de AddingNewCustomer. Elle sera utilisée pour désactiver les boutons de la barre de commande lorsque le panneau est visible.
public bool EnableCommandBar => !AddingNewCustomer;
Vous allez maintenant avoir besoin d'un moyen d'afficher le panneau pliable et de créer un client à éditer à l'intérieur de celui-ci.
Ajoutez une nouvelle propriété privée et une nouvelle propriété publique au ViewModel, pour contenir le client nouvellement créé.
private CustomerViewModel _newCustomer; public CustomerViewModel NewCustomer { get => _newCustomer; set { if (_newCustomer != value) { _newCustomer = value; OnPropertyChanged(); } } }
Mettez à jour votre méthode CreateNewCustomerAsync pour créer un nouveau client, l'ajouter au référentiel et en faire le client sélectionné :
public async Task CreateNewCustomerAsync() { CustomerViewModel newCustomer = new CustomerViewModel(new Models.Customer()); NewCustomer = newCustomer; await App.Repository.Customers.UpsertAsync(NewCustomer.Model); AddingNewCustomer = true; }
Mettez à jour la méthode SaveInitialChangesAsync pour ajouter un nouveau client au référentiel, mettre à jour l'interface utilisateur et fermer le panneau.
public async Task SaveInitialChangesAsync() { await App.Repository.Customers.UpsertAsync(NewCustomer.Model); await UpdateCustomersAsync(); AddingNewCustomer = false; }
Ajoutez la ligne de code suivante comme dernière ligne du setter pour AddingNewCustomer :
OnPropertyChanged(nameof(EnableCommandBar));
Cela garantit que EnableCommandBar est automatiquement mis à jour chaque fois que AddingNewCustomer est modifié.
Mettre à jour l’interface utilisateur
Retournez à Views\CustomerListPage.xaml, et ajoutez un StackPanel avec les propriétés suivantes entre votre CommandBar et votre grille de données :
<StackPanel x:Name="newCustomerPanel" Orientation="Horizontal" x:Load="{x:Bind ViewModel.AddingNewCustomer, Mode=OneWay}" RelativePanel.Below="mainCommandBar"> </StackPanel>
L'attribut x:Load garantit que ce panneau n'apparaît que lorsque vous ajoutez un nouveau client.
Apportez la modification suivante à la position de votre grille de données, afin qu'elle se déplace vers le bas lorsque le nouveau panneau apparaît :
RelativePanel.Below="newCustomerPanel"
Mettez à jour votre panneau de pile avec quatre contrôles TextBox. Ils seront liés aux propriétés individuelles du nouveau client et vous permettront de modifier ses valeurs avant de l'ajouter à la grille de données.
<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>
Ajoutez un simple bouton à votre nouveau panneau de pile pour enregistrer le client nouvellement créé :
<StackPanel> <!--Text boxes from step 3--> <AppBarButton x:Name="SaveNewCustomer" Click="{x:Bind ViewModel.SaveInitialChangesAsync}" Icon="Save"/> </StackPanel>
Mettez à jour la CommandBar de manière à ce que les boutons de création, de suppression et de mise à jour soient désactivés lorsque le panneau de pile est visible :
<CommandBar x:Name="mainCommandBar" HorizontalAlignment="Stretch" IsEnabled="{x:Bind ViewModel.EnableCommandBar, Mode=OneWay}" Background="AliceBlue"> <!--App bar buttons--> </CommandBar>
Lancez votre application. Vous pouvez désormais créer un client et saisir ses données dans le panneau de pile.
Partie 7 : Supprimer un client
La suppression d'un client est la dernière opération de base que vous devez mettre en œuvre. Lorsque vous supprimez un client sélectionné dans la grille de données, vous devez immédiatement appeler UpdateCustomersAsync afin de mettre à jour l'interface utilisateur. Cependant, vous n'avez pas besoin d'appeler cette méthode si vous supprimez un client que vous venez de créer.
Accédez à ViewModels\CustomerListPageViewModel.cs et mettez à jour la méthode DeleteAndUpdateAsync :
public async void DeleteAndUpdateAsync() { if (SelectedCustomer != null) { await App.Repository.Customers.DeleteAsync(_selectedCustomer.Model.Id); } await UpdateCustomersAsync(); }
Dans Views\CustomerListPage.xaml, mettez à jour le panneau de pile pour l'ajout d'un nouveau client afin qu'il contienne un deuxième bouton :
<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>
Dans ViewModels\CustomerListPageViewModel.cs, mettez à jour la méthode DeleteNewCustomerAsync pour supprimer le nouveau client :
public async Task DeleteNewCustomerAsync() { if (NewCustomer != null) { await App.Repository.Customers.DeleteAsync(_newCustomer.Model.Id); AddingNewCustomer = false; } }
Lancez votre application. Vous pouvez maintenant supprimer des clients, soit dans la grille de données, soit dans le panneau de pile.
Conclusion
Félicitations ! Une fois toutes ces opérations effectuées, votre application dispose désormais d'une gamme complète d'opérations sur les bases de données locales. Vous pouvez créer, lire, mettre à jour et supprimer des clients dans votre interface utilisateur, et ces modifications sont enregistrées dans votre base de données et persistent lors des différents lancements de votre application.
Maintenant que vous avez terminé, réfléchissez aux points suivants :
- Si vous ne l'avez pas encore fait, consultez l'aperçu de la structure de l'application pour plus d'informations sur les raisons pour lesquelles l'application est construite comme elle l'est.
- Explorez l'exemple complet de base de données des commandes clients pour voir l'application sur laquelle ce tutoriel est basé.
Ou si vous êtes prêt à relever un défi, vous pouvez continuer...
Aller plus loin : Se connecter à une base de données distante
Nous avons fourni une procédure pas-à-pas sur la façon d'implémenter ces appels à une base de données SQLite locale. Mais que se passe-t-il si vous souhaitez utiliser une base de données distante ?
Si vous voulez essayer, vous aurez besoin de votre propre compte Azure Active Directory (AAD) et de la possibilité d'héberger votre propre source de données.
Vous devrez ajouter l'authentification, des fonctions pour gérer les appels REST, puis créer une base de données distante avec laquelle interagir. L'exemple complet de base de données des commandes clients contient du code auquel vous pouvez vous référer pour chaque opération nécessaire.
Paramètres et configuration
Les étapes nécessaires pour se connecter à votre propre base de données distante sont expliquées dans le fichier readme de l'exemple. Vous devez effectuer ce qui suit :
- Fournissez l'ID client de votre compte Azure à Constants.cs.
- Fournissez l'url de la base de données distante à Constants.cs.
- Fournissez la chaîne de connexion de la base de données à Constants.cs.
- Associer votre application à Microsoft Store.
- Copiez le projet Service dans votre application et déployez-la sur Azure.
Authentification
Vous devrez créer un bouton pour lancer une séquence d'authentification et une fenêtre contextuelle ou une page séparée pour recueillir les informations de l'utilisateur. Une fois ces éléments créés, vous devrez fournir un code qui demande les informations de l'utilisateur et les utilise pour acquérir un jeton d'accès. L'exemple de base de données des commandes clients intègre les appels Microsoft Graph à la bibliothèque WebAccountManager pour acquérir un jeton et gérer l'authentification à un compte AAD.
- La logique d'authentification est mise en œuvre dans AuthenticationViewModel.cs.
- Le processus d'authentification est affiché dans le contrôle personnalisé AuthenticationControl.xaml.
Appels REST
Vous n'aurez pas besoin de modifier le code que nous avons ajouté dans ce tutoriel pour mettre en œuvre les appels REST. Au lieu de cela, vous devrez faire ce qui suit :
- Créez de nouvelles implémentations des interfaces ICustomerRepository et ITutorialRepository, en implémentant le même ensemble de fonctions via REST au lieu de SQLite. Vous devrez sérialiser et désérialiser JSON, et vous pouvez envelopper vos appels REST dans une classe HttpHelper séparée si nécessaire. Reportez-vous à l'exemple complet pour plus de détails.
- Dans App.xaml.cs, créez une nouvelle fonction pour initialiser le référentiel REST et appelez-la au lieu de SqliteDatabase lorsque l'application est initialisée. Là encore, reportez-vous à l'exemple complet.
Une fois ces trois étapes terminées, vous devriez être en mesure de vous authentifier à votre compte AAD via votre application. Les communications REST vers la base de données distante remplaceront les communications SQLite locales, mais l'expérience utilisateur devrait être la même. Si vous vous sentez encore plus ambitieux, vous pouvez ajouter une page de configuration pour permettre à l'utilisateur de basculer dynamiquement entre les deux.