建立互動式 UI

已完成

Tech logo.

在先前的課程中,您已建置簡單的表單 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,其預設是設定為 LostFocusUpdateSourceTrigger 會定義造成來源更新的情況。

請開啟 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 本身具有豐富的驗證功能,我們將在稍後的課程模組中加以說明。

Screenshot of app, with Submit button disabled.

9. 隱藏 [Submit] (\提交\) 按鈕

您或您的設計人員可能會決定要更進一步,並實際隱藏 [Submit] \(提交\) 按鈕,直到使用者可以按下它為止。 這是個簡單的變更,因此讓我們立即進行。 您只須編輯 XAML,並將 IsEnabled 變更為 Visibility 即可。

Screenshot of app, with Submit button hidden.

不過,如果您輸入幾個字元,就會看到整個 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 的外觀和行為。

在下一課中,我們將探討如何使用資料繫結在清單中顯示多個項目。

Tech logo.

在先前的課程中,您建立了簡單的表單 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,其預設是設定為 LostFocusUpdateSourceTrigger 會定義造成來源更新的情況。

開啟 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 本身具有一系列豐富的驗證功能,將會在接續的課程模組中加以說明。

Screenshot of app, with Submit button disabled.

摘要

在此課程中,您已了解如何對繫結進行偵錯。 您已了解 UpdateSourceTrigger 繫結選項,並已查看進一步的資料繫結範例。 您也看到範例示範如何在正確使用資料繫結的情況下,無須動到 C# 程式碼就能變更 UI 的外觀和行為。

在下一課中,我們將探討如何使用資料繫結在清單中顯示多個項目。