教學課程:建立客戶資料庫應用程式
本文內容
第 1 部分:興趣程式碼
第 2 部分:新增 DataGrid
第 3 部分:閱讀客戶
第 4 部分:編輯客戶
第 5 部分:更新客戶
第 6 部分:建立新客戶
第 7 部分:刪除客戶
結論
進一步:連線至遠端資料庫
顯示其他 5 個
本教學課程會建立一個簡單的應用程式來管理客戶清單。 為此,它會介紹 UWP 中企業應用程式的一系列基本概念。 您將學習如何:
對本機 SQL 資料庫實作建立、讀取、更新和刪除作業。
新增資料格,以在 UI 中顯示和編輯客戶資料。
將 UI 元素排列在基本表單佈局中。
本教程以具有最少 UI 和功能的單頁應用程序作為開頭,以簡化的客戶訂單資料庫範例應用程式 版本為基礎。 它是以 C# 和 XAML 撰寫,我們預期您已基本熟悉這兩種語言。
複製/下載存放庫之後,就可以使用 Visual Studio 開啟 CustomerDatabaseTutorial.sln 來編輯專案。
注意
本教學課程是以客戶訂單資料庫範例 為基礎,該範例最近已更新為使用 WinUI 和 Windows 應用程式 SDK。 在本教學課程和程式碼更新之前,這兩個範例之間將會存在差異。
如果您在打開應用程式後立即運行,您會在空白畫面頂端看到幾個按鈕。 雖然您看不到,但該應用程式已經包含一個由幾位測試客戶佈建的本機 SQLite 資料庫。 從這裡開始,您將先實作一個 UI 控制項來顯示這些客戶,然後繼續新增針對資料庫的作業。 在開始之前,以下是您將執行動作的地方。
CustomerListPage.xaml 是應用程式的視圖,其定義本教學課程中單一頁面的 UI。 每當您需要在 UI 中新增或變更視覺元素時,都可以在此檔案中完成。 本教學將引導您新增以下元素:
RadDataGrid ,用來顯示和編輯客戶。
StackPanel ,可設定新客戶的初始值。
ViewModels\CustomerListPageViewModel.cs ,這是應用程式基本邏輯所在的位置。 在視圖中執行的每個使用者動作都會傳遞到此檔案中進行處理。 在本教程中,您將添加一些新程式碼,並實作以下方法:
CreateNewCustomerAsync ,初始化新的 CustomerViewModel 物件。
DeleteNewCustomerAsync ,它會先移除新客戶,再將其顯示在 UI 中。
DeleteAndUpdateAsync ,其可處理刪除按鈕的邏輯。
GetCustomerListAsync ,其會從資料庫擷取客戶清單。
SaveInitialChangesAsync ,其會將新的客戶資訊新增至資料庫。
UpdateCustomersAsync ,其會重新整理 UI,以反映任何新增或刪除的客戶。
CustomerViewModel ,是客戶資訊的包裝函式,可追蹤它是否最近修改過。 您不需要向此類別添加任何內容,但您在其他地方添加的部分程式碼將引用它。
有關如何建構範例的詳細資訊,請參閱應用程序結構概觀 。
開始對客戶資料進行操作之前,您需要新增一個 UI 控制項來顯示這些客戶。 若要這樣做,我們將使用預先製作的第三方 RadDataGrid 控制項。 Telerik.UI.for.UniversalWindowsPlatform NuGet 套件已包含在此專案中。 讓我們將網格線新增至專案。
從「方案總管」開啟 Views\CustomerListPage.xaml 。 在 Page 標籤中新增以下程式代碼行,以宣告對應至包含數據格的 Telerik 命名空間。
xmlns:telerikGrid="using:Telerik.UI.Xaml.Controls.Grid"
在視圖的主要 RelativePanel 內的 CommandBar 下方,新增 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 將為您處理大部分 UI 邏輯。 不過,如果您執行專案,仍然不會看到任何資料。 那是因為 ViewModel 尚未載入資料。
初始化後,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));
}
});
}
載入 ViewModel 時會呼叫 GetCustomerListAsync 方法,但在此步驟之前,其不會執行任何動作。 在這裡,我們已在 Repository/SqlCustomerRepository 中新增 GetAsync 方法的呼叫。 這可讓其連絡存放庫以擷取 Customer 物件的可列舉集合。 然後,它會將它們剖析成個別物件,再將它們新增至其內部 ObservableCollection ,以便顯示和編輯它們。
執行您的應用程式 - 您現在會看到顯示客戶清單的資料格。
您可以按兩下資料格中的項目來進行編輯,但您必須確定您在 UI 中所做的任何變更也會對程式碼後置中的客戶集合進行變更。 這表示您必須實作雙向數據系結。 如果您想了解更多相關資訊,請參閱我們的數據系結簡介 。
首先,宣告 ViewModels\CustomerListPageViewModel.cs 實作 INotifyPropertyChanged 介面:
public class CustomerListPageViewModel : INotifyPropertyChanged
然後,在類別的主體中,新增以下事件和方法:
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
OnPropertyChanged 方法可讓您的 setter 輕鬆引發 PropertyChanged 事件,這對於雙向資料綁定是必要的。
使用下列函數呼叫更新 SelectedCustomer 的 setter:
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 綁定模式可讓您在 UI 中所做的變更反映在該物件上。
執行應用程式。 現在您可以查看網格中顯示的客戶,並透過 UI 對基礎資料進行變更。
現在您可以查看和編輯客戶,您需要能夠將變更推送到資料庫,並提取其他人所做的任何更新。
返回 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();
}
此程式代碼會利用 ViewModels\CustomerViewModel.cs 的 IsModified 屬性,每當客戶變更時就會自動更新。 這可讓您避免不必要的呼叫,並只將更新的客戶變更推送至資料庫。
新增客戶是一項挑戰,因為如果您在為其屬性提供值之前將其新增至 UI,則該客戶將顯示為空白行。 這不是個問題,但在這裡,我們將能更輕鬆設定客戶的初始值。 在本教學課程中,我們將新增簡單的可折疊面板,但如果您有更多資訊要新增,您可以為此一個單獨的頁面。
將新的私人欄位和公用屬性新增至 ViewModels\CustomerListPageViewModel.cs 。 這會用來控制面板是否可見。
private bool _addingNewCustomer = false;
public bool AddingNewCustomer
{
get => _addingNewCustomer;
set
{
if (_addingNewCustomer != value)
{
_addingNewCustomer = value;
OnPropertyChanged();
}
}
}
在 ViewModel 新增一個新的公用屬性,該屬性與 AddingNewCustomer 的值相反。 當面板可見時,這將用於停用一般命令列按鈕。
public bool EnableCommandBar => !AddingNewCustomer;
現在您需要一種方法來顯示可折疊面板,並建立一個客戶以在其中進行編輯。
在 ViewModel 新增一個新的私人 fiend 和公用屬性,以儲存新建立的客戶。
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 方法,將新建立的客戶新增至存放庫、更新 UI,然後關閉面板。
public async Task SaveInitialChangesAsync()
{
await App.Repository.Customers.UpsertAsync(NewCustomer.Model);
await UpdateCustomersAsync();
AddingNewCustomer = false;
}
將以下程式碼行新增為 AddingNewCustomer 中 setter 的最後一行:
OnPropertyChanged(nameof(EnableCommandBar));
這將確保每當 AddingNewCustomer 發生變更時,EnableCommandBar 都會自動更新。
導覽回 Views\CustomerListPage.xaml ,並在 CommandBar 和資料網格之間新增具有以下屬性的 StackPanel :
<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>
執行應用程式。 您現在可以建立客戶,並在堆疊面板中輸入其數據。
刪除客戶是您需要實作的最後一個基本作業。 當您刪除在資料格中選取的客戶時,您需要立即呼叫 UpdateCustomersAsync 以更新 UI。 但是,如果您要刪除剛剛建立的客戶,則無需呼叫該方法。
流覽至 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;
}
}
執行應用程式。 您現在可以在資料格內或堆疊面板中刪除客戶。
恭喜! 完成這一切之後,您的應用程式現在已擁有完整的本機資料庫作業。 您可以在 UI 內建立、讀取、更新和刪除客戶,這些變更會儲存至您的資料庫,並會在應用程式的不同啟動中持續存在。
現在您已完成整個流程,請考慮下列事項:
或者,如果您準備好迎接挑戰,您可以繼續前進...
我們已逐步解說如何針對本機 SQLite 資料庫實作這些呼叫。 但如果您想要改用遠端資料庫,該怎麼辦?
如果您想嘗試一下,您需要自己的 Azure Active Directory (AAD) 帳戶,以及託管資料來源的能力。
您需要新增驗證、處理 REST 呼叫的函數,然後建立一個遠端資料庫進行互動。 完整的客戶訂單資料庫範例 中有程式碼,您可以參考每個必要的作業。
範例的自述文件 中詳細說明了連接到您遠端資料庫的必要步驟。 您需要執行下列作業:
您需要建立一個按鈕來啟動驗證序列,並建立一個快顯視窗或單獨的頁面來收集使用者資訊。 建立之後,您必須提供程式碼來要求使用者的資訊,並使用其來取得存取令牌。 客戶訂單資料庫範例會使用 WebAccountManager 程式庫包裝 Microsoft Graph 呼叫,以取得令牌並處理 AAD 帳戶的驗證。
您無需修改我們在本教程中新增的任何程式碼即可實作 REST 呼叫。 但您需要執行下列作業:
建立 ICustomerRepository 和 ITutorialRepository 介面的新實作,透過 REST 而不是 SQLite 實作相同的函數集。 您需要序列化和反序列化 JSON,並且如果需要,可以將 REST 呼叫包裝在單獨的 HttpHelper 類別中。 有關詳細資訊,請參閱完整範例 。
在 App.xaml.cs 中,建立一個新函數來初始化 REST 儲存庫,並在初始化應用程式時呼叫它,而不是 SqliteDatabase 。 同樣地,請參閱完整的範例 。
完成上述三個步驟之後,您應該能夠透過應用程式對 AAD 帳戶進行驗證。 對遠端資料庫的 REST 呼叫將會取代本機 SQLite 呼叫,但使用者體驗應該是相同的。 如果您想更進一步,則可以新增設定頁面,讓使用者在兩者之間動態切換。