建立互動式 UI
在先前的課程中,您已建置簡單的表單 UI、提示使用者輸入名稱,並透過按鈕顯示問候語。 在此課程中,您透過停用或隱藏 [提交] 按鈕,直到使用者至少輸入三個字元為止,讓表單變得稍微更方便使用。
首先,讓我們檢查透過繫結設定 MainPageLogic.UserName
值的確切時機。
1. 放置中斷點
請開啟 MainPageLogic.cs
檔案,然後尋找包含 UserName
屬性的行。
public string UserName { get; set; }
透過移動 set
文字內的插入點,然後按 F9,來在 setter 上設定中斷點。 也能以滑鼠右鍵按一下 set
,然後選取 [中斷點] / [插入中斷點] 來完成這項操作。
2. 在偵錯模式中執行應用程式
接著,以偵錯模式執行應用程式 (F5 或 [偵錯] / [開始偵錯])。 在 TextBox
中進行一些輸入,並請注意,並不會發生中斷點叫用。 如果您按 Tab 鍵,它會將輸入焦點移至下一個控制項 (在我們的案例中為按鈕)。 當 TextBox
失去焦點時,即會更新繫結,因此會叫用中斷點。
3. 變更繫結,讓它在每次按鍵輸入時都進行更新
請按 Shift+F5 或選取 [偵錯] / [停止偵錯] 來停止偵錯。
為了提供有關 [提交] 按鈕啟用時機的精確回饋,我們不能等到 TextBox
失去焦點。 幸運的是,有可以用來變更繫結行為的方法。 您會強制它在每次文字屬性變更時更新 UserName
屬性 (其為來源,因為我們目前談論的是 TwoWay
繫結)。 我們必須變更繫結的 UpdateSourceTrigger
,其預設是設定為 LostFocus
。 UpdateSourceTrigger
會定義造成來源更新的情況。
請開啟 MainPage.xaml,然後尋找 TextBox
。 接著,新增 UpdateSourceTrigger=PropertyChanged
來變更繫結。 整個 TextBox
標籤現在應該看起來像這樣:
<TextBox Name="tbUserName"
Margin="10"
Width="150"
VerticalAlignment="Center"
Text="{x:Bind Logic.UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
如果您現在對應用程式進行偵錯,便可以看到隨著每次的按鍵輸入和文字變更,都會叫用中斷點。 太棒了!
您可能還記得我們使用 UI 對 UI 繫結來顯示問候語時,每次按鍵輸入都會引發繫結。 在該案例中,是在 TextBlock
上定義繫結,因此來源是 TextBox.Text
屬性,其確實會隨著每次按鍵輸入而發生變更。 UpdateSourceTrigger
影響另一個方向的資料流程。 其從繫結來源流向所定義的繫結控制項 (繫結目標)。
5. 新增 IsSubmitAllowed
屬性
接著,您將會新增能指出是否允許提交表單的布林值屬性。 請開啟 MainPageLogic.cs,然後將新的屬性新增至 MainPageLogic
類別。
public bool IsSubmitAllowed => UserName?.Trim().Length > 2;
這是個非常簡單的驗證:如果輸入的文字在截斷前置和尾端空白字元後包含兩個以上的字元,我們便接受它作為使用者名稱。
6. 每次對 UserName
進行變更之後,都重新評估 IsSubmitAllowed
我們必須告訴 UI 架構何時重新評估此屬性並反映在 UI 上。 觸發此重新評估的最佳方式是在 UserName
屬性的 Setter 中叫用 RaisePropertyChanged
。 為了能夠將程式碼新增至 setter,必須將其轉換成完整屬性。 以下列程式碼來取代 UserName
屬性:
private string _userName;
public string UserName
{
get { return _userName; }
set
{
_userName = value;
RaisePropertyChanged(nameof(IsSubmitAllowed));
}
}
我們並未將 INotifyPropertyChanged
用於此屬性,因為我們尚未從程式碼變更 UserName
屬性的情況。 不過,每次 TextBox
中的文字變更時,我們都必須告訴 UI IsSubmitAllowed
屬性可能已變更且應該重新評估。
7. 將 IsSubmitAllowed
屬性繫結至按鈕的 IsEnabled
屬性
現在您已完成程式碼。 請回到 MainPage.xaml,然後尋找 [提交] 按鈕。 新增 IsEnabled
屬性,讓按鈕的 XAML 現在看起來像這樣:
<Button Margin="10"
VerticalAlignment="Center"
Click="{x:Bind Logic.Submit}"
IsEnabled="{x:Bind Logic.IsSubmitAllowed, Mode=OneWay}">Submit</Button>
8. 執行應用程式
如果您現在執行應用程式,應該會看到 [提交] 按鈕預設為停用。 如果您輸入幾個空格,它會繼續保持停用,只有當至少輸入三個非空白字元時,才會啟用。
雖然此範例會執行一些驗證,UWP 本身具有豐富的驗證功能,我們將在稍後的課程模組中加以說明。
9. 隱藏 [Submit] (\提交\) 按鈕
您或您的設計人員可能會決定要更進一步,並實際隱藏 [Submit] \(提交\) 按鈕,直到使用者可以按下它為止。 這是個簡單的變更,因此讓我們立即進行。 您只須編輯 XAML,並將 IsEnabled
變更為 Visibility
即可。
不過,如果您輸入幾個字元,就會看到整個 UI 跳動。 這是因為周圍的 StackPanel
都以水平方式置中 (HorizontalAlignment="Center"
),而當 Button
處於摺疊狀態時,StackPanel
的寬度便會較小。 若要解決此問題,您可以將 Button
放在 100 單位寬的 Border
中即可,就像這樣。
<Border Width="100">
<Button Margin="10"
VerticalAlignment="Center"
Click="{x:Bind Logic.Submit}"
Visibility="{x:Bind Logic.IsSubmitAllowed, Mode=OneWay}">Submit</Button>
</Border>
透過此方式,當 Border
內的 Button
重新出現時,StackPanel
的寬度就不會變更。
摘要
在此課程中,您已了解如何對繫結進行偵錯。 您已了解 UpdateSourceTrigger
繫結選項,並已查看進一步的資料繫結範例。 您也看到範例示範如何在正確使用資料繫結的情況下,無須動到 C# 程式碼就能變更 UI 的外觀和行為。
在下一課中,我們將探討如何使用資料繫結在清單中顯示多個項目。
在先前的課程中,您建立了簡單的表單 UI、提示使用者輸入名稱,並透過按鈕顯示問候語。 在此課程中,您透過停用或隱藏 [提交] 按鈕,直到使用者至少輸入三個字元為止,讓表單變得稍微更方便使用。
首先,讓我們檢查透過繫結設定 MainWindowDataContext.UserName
值的確切時機。
1. 放置中斷點
請開啟 MainWindowDataContext.cs
檔案,然後尋找包含 UserName
屬性的行。
public string UserName { get; set; }
透過移動 set
文字內的插入點,然後按 F9,來在 setter 上設定中斷點。 也能以滑鼠右鍵按一下 set
,然後選取 [中斷點] / [插入中斷點] 來完成這項操作。
2. 在偵錯模式中執行應用程式
接著,以偵錯模式執行應用程式 (F5 或 [偵錯] / [開始偵錯])。 在 TextBox
中進行一些輸入,並請注意,並不會發生中斷點叫用。 如果您按 Tab 鍵,它會將輸入焦點移至下一個控制項 (在我們的案例中為按鈕)。 當 TextBox
失去焦點時,即會更新繫結,因此會叫用中斷點。
3. 變更繫結,讓它在每次按鍵輸入時都進行更新
請按 Shift+F5 或選取 [偵錯] / [停止偵錯] 來停止偵錯。
為了提供有關 [提交] 按鈕啟用時機的精確回饋,我們不能等到 TextBox
失去焦點。 幸運的是,有可以用來變更繫結行為的方法。 您會強制它在每次文字屬性變更時更新 UserName
屬性 (其為來源,因為我們目前談論的是 TwoWay
繫結)。 我們必須變更繫結的 UpdateSourceTrigger
,其預設是設定為 LostFocus
。 UpdateSourceTrigger
會定義造成來源更新的情況。
開啟 MainWindow.xaml
,然後尋找 TextBox
。 接著,新增 UpdateSourceTrigger=PropertyChanged
來變更繫結。 整個 TextBox
標籤現在應該看起來像這樣:
<TextBox Name="tbName"
Margin="10"
Width="150"
VerticalAlignment="Center"
Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
如果您現在對應用程式進行偵錯,便可以看到隨著每次的按鍵輸入和文字變更,都會叫用中斷點。 太棒了!
您可能還記得我們使用 UI 對 UI 繫結來顯示問候語時,每次按鍵輸入都會觸發繫結。 在該案例中,是在 TextBlock
上定義繫結,因此來源是 TextBox.Text
屬性,其確實會隨著每次按鍵輸入而發生變更。 UpdateSourceTrigger
影響另一個方向的資料流程。 其從繫結來源流向所定義的繫結控制項 (繫結目標)。
5. 新增 IsSubmitAllowed
屬性
接著,您將會新增能指出是否允許提交表單的布林值屬性。 請開啟 MainWindowDataContext.cs
,然後將新的屬性新增至 MainWindowDataContext
類別。
public bool IsSubmitAllowed => !string.IsNullOrWhiteSpace(UserName);
此屬性正在執行簡易驗證。 如果輸入的文字不是 Null、空白或純空白字元,我們會將其接受為使用者名稱。
6. 每次對 UserName
進行變更之後,都重新評估 IsSubmitAllowed
我們必須告訴 UI 架構何時重新評估此屬性並反映在 UI 上。 觸發此重新評估的最佳方式是在 UserName
屬性的 Setter 中叫用 RaisePropertyChanged
。 為了能夠將程式碼新增至 setter,必須將其轉換成完整屬性。 以下列程式碼來取代 UserName
屬性:
private string? _userName;
public string? UserName
{
get { return _userName; }
set
{
_userName = value;
RaisePropertyChanged(nameof(IsSubmitAllowed));
}
}
我們並未將 INotifyPropertyChanged
用於此屬性,因為我們沒有從程式碼變更 UserName
屬性的情況。 不過,每次 TextBox
中的文字變更時,我們都必須告訴 UI IsSubmitAllowed
屬性可能已變更且應該重新評估。
7. 將 IsSubmitAllowed
屬性繫結至按鈕的 IsEnabled
屬性
現在您已完成程式碼。 請回到 MainWindow.xaml
,然後尋找 [Submit] \(提交\) 按鈕。 新增 IsEnabled
屬性,讓按鈕的 XAML 現在看起來像這樣:
<Button Margin="10"
VerticalAlignment="Center"
Click="OnSubmitClicked"
IsEnabled="{Binding IsSubmitAllowed}">Submit</Button>
8. 執行應用程式
如果您現在執行應用程式,應該會看到 [提交] 按鈕預設為停用。 只要您一在其中進行輸入,就會立即啟用。
雖然此範例會執行一些基本驗證,但 WPF 本身具有一系列豐富的驗證功能,將會在接續的課程模組中加以說明。
摘要
在此課程中,您已了解如何對繫結進行偵錯。 您已了解 UpdateSourceTrigger
繫結選項,並已查看進一步的資料繫結範例。 您也看到範例示範如何在正確使用資料繫結的情況下,無須動到 C# 程式碼就能變更 UI 的外觀和行為。
在下一課中,我們將探討如何使用資料繫結在清單中顯示多個項目。