Руководство: создание приложения базы данных клиентов
В этом руководстве создается простое приложение для управления списком клиентов. При этом в нем представлен ряд основных понятий для корпоративных приложений в UWP. Вы узнаете, как:
- Реализуйте операции создания, чтения, обновления и удаления в локальной базе данных SQL.
- Добавьте сетку данных для отображения и изменения данных клиентов в пользовательском интерфейсе.
- Расположите элементы пользовательского интерфейса в базовом макете формы.
Отправной точкой для работы с этим руководством является одностраничное приложение с минимальными возможностями пользовательского интерфейса и функциональными возможностями, основанное на упрощенной версии примера приложения Базы данных заказов клиентов. Она написана на C# и XAML, и мы ожидаем, что у вас есть базовое знакомство с обоими этими языками.
Предварительные требования
- Убедитесь, что у вас установлена последняя версия Visual Studio и Windows SDK.
- Клонирование или скачивание примера руководства по базе данных клиента
После клонированного или скачав репозиторий, вы можете изменить проект, открыв CustomerDatabaseTutorial.sln в Visual Studio.
Примечание
Это руководство основано на примере базы данных заказов клиентов, который недавно был обновлен для использования WinUI и Windows App SDK. Пока этот учебник и код не будут обновлены, между двумя примерами будут различия.
Часть 1. Код интереса
Если вы запустите приложение сразу после его открытия, вы увидите несколько кнопок в верхней части пустого экрана. Хотя это приложение невидимо для вас, приложение уже включает локальную базу данных SQLite, подготовленную для нескольких тестовых клиентов. Здесь вы начнете с реализации элемента управления пользовательского интерфейса для отображения этих клиентов, а затем перейдете к добавлению операций в базе данных. Прежде чем начать, вот где вы будете работать.
Представления
CustomerListPage.xaml — это представление приложения, которое определяет пользовательский интерфейс для одной страницы в этом руководстве. Каждый раз, когда вам нужно добавить или изменить визуальный элемент в пользовательском интерфейсе, вы будете делать это в этом файле. В этом руководстве описано, как добавить следующие элементы:
- RadDataGrid для отображения и редактирования клиентов.
- StackPanel для задания начальных значений для нового клиента.
Модели представлений
ViewModels\CustomerListPageViewModel.cs — это расположение основной логики приложения. Каждое действие пользователя, выполняемое в представлении, будет передано в этот файл для обработки. В этом руководстве вы добавите новый код и реализуете следующие методы:
- CreateNewCustomerAsync, который инициализирует новый объект CustomerViewModel.
- DeleteNewCustomerAsync, который удаляет нового клиента перед его отображением в пользовательском интерфейсе.
- DeleteAndUpdateAsync, который обрабатывает логику кнопки удаления.
- GetCustomerListAsync, который получает список клиентов из базы данных.
- SaveInitialChangesAsync, который добавляет сведения о клиенте в базу данных.
- UpdateCustomersAsync, который обновляет пользовательский интерфейс, чтобы отразить все добавленные или удаленные клиенты.
CustomerViewModel — это оболочка для сведений о клиенте, которая отслеживает, была ли она недавно изменена. Вам не нужно ничего добавлять в этот класс, но часть кода, который вы добавите в другое место, будет ссылаться на него.
Дополнительные сведения о создании примера проверка в обзоре структуры приложения.
Часть 2. Добавление DataGrid
Прежде чем приступить к работе с данными клиентов, необходимо добавить элемент управления пользовательского интерфейса для отображения этих клиентов. Для этого мы будем использовать готовый сторонний элемент управления RadDataGrid . Пакет NuGet Telerik.UI.for.UniversalWindowsPlatform уже включен в этот проект. Давайте добавим сетку в проект.
Откройте Файл Views\CustomerListPage.xaml из Обозреватель решений. Добавьте следующую строку кода в тег Page , чтобы объявить сопоставление с пространством имен Telerik, содержащим сетку данных.
xmlns:telerikGrid="using:Telerik.UI.Xaml.Controls.Grid"
Под панелью CommandBar в main RelativePanel представления добавьте элемент управления RadDataGrid с некоторыми базовыми параметрами конфигурации:
<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>
Вы добавили сетку данных, но для ее отображения требуются данные. Добавьте в него следующие строки кода:
ItemsSource="{x:Bind ViewModel.Customers}" UserEditMode="Inline"
Теперь, когда вы определили источник данных для отображения, RadDataGrid будет обрабатывать большую часть логики пользовательского интерфейса. Однако при запуске проекта вы по-прежнему не увидите никаких данных на экране. Это связано с тем, что ViewModel еще не загружает его.
Часть 3. Чтение клиентов
При инициализации viewModels\CustomerListPageViewModel.cs вызывает метод GetCustomerListAsync . Этот метод должен получить тестовые данные клиента из базы данных SQLite, которая включена в учебник.
В файле ViewModels\CustomerListPageViewModel.cs обновите метод GetCustomerListAsync , используя следующий код:
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)); } }); }
Метод GetCustomerListAsync вызывается при загрузке ViewModel, но до этого шага он ничего не делал. Здесь мы добавили вызов метода GetAsync в Repository/SqlCustomerRepository. Это позволяет ему связаться с репозиторием, чтобы получить перечисляемую коллекцию объектов Customer. Затем он анализирует их в отдельные объекты, прежде чем добавлять их во внутреннюю коллекцию ObservableCollection , чтобы их можно было отображать и редактировать.
Запустите приложение. Теперь вы увидите сетку данных со списком клиентов.
Часть 4. Изменение клиентов
Вы можете изменить записи в сетке данных, дважды щелкнув их, но необходимо убедиться, что все изменения, внесенные в пользовательском интерфейсе, также будут вноситься в вашу коллекцию клиентов в коде программной части. Это означает, что вам придется реализовать двусторонняя привязка данных. Если вам нужны дополнительные сведения об этом, проверка знакомство с привязкой данных.
Сначала объявите, что файл ViewModels\CustomerListPageViewModel.cs реализует интерфейс INotifyPropertyChanged :
public class CustomerListPageViewModel : INotifyPropertyChanged
Затем в main теле класса добавьте следующие событие и метод:
public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
Метод OnPropertyChanged упрощает создание события PropertyChanged , необходимого для двусторонней привязки данных.
Обновите метод задания для SelectedCustomer с помощью следующего вызова функции:
public CustomerViewModel SelectedCustomer { get => _selectedCustomer; set { if (_selectedCustomer != value) { _selectedCustomer = value; OnPropertyChanged(); } } }
В файле Views\CustomerListPage.xaml добавьте свойство SelectedCustomer в сетку данных.
SelectedItem="{x:Bind ViewModel.SelectedCustomer, Mode=TwoWay}"
Это связывает выбор пользователя в сетке данных с соответствующим объектом Customer в коде программной части. Режим привязки TwoWay позволяет отражать изменения, внесенные в пользовательском интерфейсе, в этом объекте.
Запустите приложение. Теперь вы можете видеть клиентов, отображаемых в сетке, и вносить изменения в базовые данные с помощью пользовательского интерфейса.
Часть 5. Обновление клиентов
Теперь, когда вы можете просматривать и изменять клиентов, необходимо иметь возможность отправлять изменения в базу данных и извлекать все обновления, внесенные другими пользователями.
Вернитесь в viewModels\CustomerListPageViewModel.cs и перейдите к методу UpdateCustomersAsync . Обновите его с помощью этого кода, чтобы отправить изменения в базу данных и получить новые сведения:
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(); }
В этом коде используется свойство IsModifiedфайла ViewModels\CustomerViewModel.cs, которое автоматически обновляется при каждом изменении клиента. Это позволяет избежать ненужных вызовов и отправлять изменения только от обновленных клиентов в базу данных.
Часть 6. Создание нового клиента
Добавление нового клиента представляет собой проблему, так как клиент будет отображаться как пустая строка, если вы добавите его в пользовательский интерфейс перед предоставлением значений для его свойств. Это не проблема, но здесь мы упростим задание начальных значений клиента. В этом руководстве мы добавим простую сворачиваемую панель, но если у вас есть дополнительные сведения, вы можете создать отдельную страницу для этой цели.
Обновление кода программной части
Добавьте новое частное поле и открытое свойство в файл ViewModels\CustomerListPageViewModel.cs. Он будет использоваться для управления видимости панели.
private bool _addingNewCustomer = false; public bool AddingNewCustomer { get => _addingNewCustomer; set { if (_addingNewCustomer != value) { _addingNewCustomer = value; OnPropertyChanged(); } } }
Добавьте новое открытое свойство в ViewModel, обратное значению AddNewCustomer. Он будет использоваться для отключения обычных кнопок панели команд, когда панель видна.
public bool EnableCommandBar => !AddingNewCustomer;
Теперь вам потребуется способ отображения сворачиваемой панели и создания клиента для редактирования в ней.
Добавьте новое частное свойство и открытое свойство в ViewModel, чтобы содержать только что созданного клиента.
private CustomerViewModel _newCustomer; public CustomerViewModel NewCustomer { get => _newCustomer; set { if (_newCustomer != value) { _newCustomer = value; OnPropertyChanged(); } } }
Обновите метод CreateNewCustomerAsync , чтобы создать нового клиента, добавить его в репозиторий и задать в качестве выбранного клиента:
public async Task CreateNewCustomerAsync() { CustomerViewModel newCustomer = new CustomerViewModel(new Models.Customer()); NewCustomer = newCustomer; await App.Repository.Customers.UpsertAsync(NewCustomer.Model); AddingNewCustomer = true; }
Обновите метод SaveInitialChangesAsync , чтобы добавить в репозиторий только что созданного клиента, обновить пользовательский интерфейс и закрыть панель.
public async Task SaveInitialChangesAsync() { await App.Repository.Customers.UpsertAsync(NewCustomer.Model); await UpdateCustomersAsync(); AddingNewCustomer = false; }
Добавьте следующую строку кода в качестве последней строки в метод задания для AddNewCustomer:
OnPropertyChanged(nameof(EnableCommandBar));
Это обеспечит автоматическое обновление EnableCommandBar при каждом изменении AddNewCustomer .
Обновление пользовательского интерфейса
Вернитесь к Views\CustomerListPage.xaml и добавьте StackPanel со следующими свойствами между commandBar и сеткой данных:
<StackPanel x:Name="newCustomerPanel" Orientation="Horizontal" x:Load="{x:Bind ViewModel.AddingNewCustomer, Mode=OneWay}" RelativePanel.Below="mainCommandBar"> </StackPanel>
Атрибут x:Load гарантирует, что эта панель отображается только при добавлении нового клиента.
Внесите следующее изменение в положение сетки данных, чтобы убедиться, что она перемещается вниз при появлении новой панели:
RelativePanel.Below="newCustomerPanel"
Обновите панель стека, используя четыре элемента управления TextBox . Они привязываются к отдельным свойствам нового клиента и позволяют изменять его значения, прежде чем добавлять их в сетку данных.
<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>
Добавьте простую кнопку на панель нового стека, чтобы сохранить только что созданного клиента:
<StackPanel> <!--Text boxes from step 3--> <AppBarButton x:Name="SaveNewCustomer" Click="{x:Bind ViewModel.SaveInitialChangesAsync}" Icon="Save"/> </StackPanel>
Обновите commandBar, чтобы обычные кнопки создания, удаления и обновления были отключены при отображении панели стека:
<CommandBar x:Name="mainCommandBar" HorizontalAlignment="Stretch" IsEnabled="{x:Bind ViewModel.EnableCommandBar, Mode=OneWay}" Background="AliceBlue"> <!--App bar buttons--> </CommandBar>
Запустите приложение. Теперь вы можете создать клиента и ввести его данные на панели стека.
Часть 7. Удаление клиента
Удаление клиента — это последняя базовая операция, которую необходимо реализовать. При удалении клиента, выбранного в сетке данных, необходимо немедленно вызвать UpdateCustomersAsync , чтобы обновить пользовательский интерфейс. Однако вам не нужно вызывать этот метод, если вы удаляете только что созданного клиента.
Перейдите в файл ViewModels\CustomerListPageViewModel.cs и обновите метод DeleteAndUpdateAsync :
public async void DeleteAndUpdateAsync() { if (SelectedCustomer != null) { await App.Repository.Customers.DeleteAsync(_selectedCustomer.Model.Id); } await UpdateCustomersAsync(); }
В файле Views\CustomerListPage.xaml обновите панель стека для добавления нового клиента, чтобы она содержала вторую кнопку:
<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>
В файле ViewModels\CustomerListPageViewModel.cs обновите метод DeleteNewCustomerAsync , чтобы удалить нового клиента:
public async Task DeleteNewCustomerAsync() { if (NewCustomer != null) { await App.Repository.Customers.DeleteAsync(_newCustomer.Model.Id); AddingNewCustomer = false; } }
Запустите приложение. Теперь вы можете удалять клиентов в сетке данных или на панели стека.
Заключение
Поздравляем! После всего этого ваше приложение теперь имеет полный спектр операций с локальной базой данных. Вы можете создавать, читать, обновлять и удалять клиентов в пользовательском интерфейсе. Эти изменения сохраняются в базе данных и будут сохраняться при различных запусках приложения.
Теперь, когда все готово, рассмотрим следующее:
- Если вы еще этого не сделали, проверка общие сведения о структуре приложения, чтобы получить дополнительные сведения о том, почему приложение создано так, как оно.
- Ознакомьтесь с полным примером базы данных заказов клиентов , чтобы увидеть приложение, на основе этого руководства.
Или если вы готовы к вызову, вы можете продолжить...
Дальнейшие действия. Подключение к удаленной базе данных
Мы предоставили пошаговое руководство по реализации этих вызовов к локальной базе данных SQLite. Но что делать, если вместо этого вы хотите использовать удаленную базу данных?
Если вы хотите попробовать, вам потребуется собственная учетная запись Azure Active Directory (AAD) и возможность размещения собственного источника данных.
Вам потребуется добавить проверку подлинности, функции для обработки вызовов REST, а затем создать удаленную базу данных для взаимодействия. В полном примере базы данных заказов клиентов есть код, на который можно ссылаться для каждой необходимой операции.
Параметры и конфигурация
Действия, необходимые для подключения к собственной удаленной базе данных, описаны в файле сведений примера. Вам понадобится выполнить следующие процедуры.
- Укажите идентификатор клиента учетной записи Azure в Файле Constants.cs.
- Укажите URL-адрес удаленной базы данных в Файле Constants.cs.
- Укажите строку подключения для базы данных к Файлу Constants.cs.
- Свяжите приложение с Microsoft Store.
- Скопируйте проект службы в приложение и разверните его в Azure.
Проверка подлинности
Вам потребуется создать кнопку для запуска последовательности проверки подлинности, а также всплывающее окно или отдельную страницу для сбора сведений о пользователе. После создания необходимо предоставить код, который запрашивает сведения о пользователе и использует их для получения маркера доступа. Пример базы данных заказов клиентов заключает вызовы Microsoft Graph в библиотеку WebAccountManager для получения маркера и обработки проверки подлинности в учетной записи AAD.
- Логика проверки подлинности реализована в файле AuthenticationViewModel.cs.
- Процесс проверки подлинности отображается в пользовательском элементе управления AuthenticationControl.xaml .
Вызовы REST
Вам не нужно изменять код, добавленный в этом руководстве, для реализации вызовов REST. Вместо этого вам потребуется выполнить следующие действия.
- Создайте новые реализации интерфейсов ICustomerRepository и ITutorialRepository , реализуя тот же набор функций с помощью REST вместо SQLite. Вам потребуется сериализовать и десериализовать JSON и при необходимости можно заключить вызовы REST в отдельный класс HttpHelper . Подробные сведения см. в полном примере .
- В Файле App.xaml.cs создайте новую функцию для инициализации репозитория REST и вызовите ее вместо SqliteDatabase при инициализации приложения. Опять же, ознакомьтесь с полным примером.
После выполнения всех трех этих действий вы сможете пройти проверку подлинности в учетной записи AAD с помощью приложения. Вызовы REST к удаленной базе данных заменяют локальные вызовы SQLite, но взаимодействие с пользователем должно быть таким же. Если вы чувствуете себя еще более амбициозным, вы можете добавить страницу параметров, чтобы позволить пользователю динамически переключаться между ними.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по