使用資料繫結來傳輸資料
在此課程中,我們會探索如何使用資料繫結來進行資料輸入,根據應用程式的狀態來顯示和隱藏某些 UI 部分。 您也會熟悉完整的 INotifyPropertyChanged
模式。
讓我們使用看起來如下的親切問候語來擴充現有的示範。
當您選取 [提交] 按鈕時,應用程式將會在頂端顯示一個簡單的問候語。
1. 開啟解決方案
如果您未在 Visual Studio 中開啟進行上一課時所建立的專案,請立即開啟。
2. 建立資料輸入 UI
資料輸入 UI 相當簡單:只是在畫面中間以單一水平配置顯示一個 TextBlock
、一個 TextBox
,以及一個 Button
。 以水平方式放置控制項最簡單的方法,是使用 StackPanel
,像這樣。
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock Margin="10"
VerticalAlignment="Center"
Text="Enter your name: "/>
<TextBox Name="tbUserName"
Margin="10"
Width="150"
VerticalAlignment="Center"/>
<Button Margin="10"
VerticalAlignment="Center" >Submit</Button>
</StackPanel>
請複製上述程式碼,並將它貼到 MainPage.xaml 的 Grid
標籤內,位於時鐘的 TextBlock
底下。
3. 實作並繫結 UserName 屬性
讓我們將注意力轉向程式碼。 開啟 MainPage.xaml.cs (您可以按 F7 來切換到程式碼後置,然後按 Shift+F7 來切換回 XAML)。 建立名為 UserName
的簡單屬性。
public string UserName { get; set; }
回到 MainPage.xaml 之後,我們可以在這個新建立的屬性與 TextBox
控制項之間建立資料繫結。 新增 Text
屬性來變更 TextBox
控制項,像這樣:
<TextBox Name="tbUserName"
Margin="10"
Width="150"
VerticalAlignment="Center"
Text="{x:Bind UserName, Mode=TwoWay}"/>
注意
在這裡,請勿混淆 TextBlock
與 TextBox
控制項。 它們在 XAML 中看起來非常相似,但如果您將 UserName
繫結至 TextBlock
的文字屬性而不是 TextBox
,則應用程式將無法運作。
透過上述程式碼,我們已在 TextBox
的 Text
屬性與程式碼中的 UserName
屬性之間建立雙向繫結。 這意謂著每當使用者輸入文字 (並將焦點從 TextBox
移開) 時,程式碼中的 UserName
屬性都會變更。 此外,TextBox
的文字會在應用程式啟動時,或每當我們以 propertyName
參數 "UserName"
引發 NotifyPropertyChanged
事件時,設定成 UserName
中儲存的值。 (我們不會在此課程中這麼做)。
4. 建立 [Submit] (提交) 按鈕的 Click 處理常式
接著,在設計介面上,按兩下 [Submit] \(提交\) 按鈕。 這會自動在程式碼中建立並開啟 Button_Click
事件。 Button_Click
不是特別合適的名稱,因此請將方法名稱變更為更具表達性的 OnSubmitClicked
。 當您完成輸入時,請按一下 OnSubmitClicked
行旁邊的燈泡。 從功能表選取 [將 'Button_Clicked' 重新命名為 'OnSubmitClicked']。 回到 XAML,確認按鈕的 XAML 現在看起來像這樣。
<Button Margin="10"
VerticalAlignment="Center"
Click="OnSubmitClicked">Submit</Button>
回到程式碼後置之後,讓我們在使用者按下按鈕時顯示簡單的對話方塊。 將下列程式碼加入 OnSubmitClicked
方法:
var dlg = new Windows.UI.Popups.MessageDialog($"Hello {UserName}!");
_ = dlg.ShowAsync();
如果您不熟悉 $"Hello {Username}"
語法,它相當於 "Hello " + UserName + "!"
或 String.Format("Hello {0}!", UserName)
。 這個更為精簡且易讀的功能被稱為字串內插補點,並已在 C# 6 中導入。
_
是 捨棄變數。 它用來指出未使用 ShowAsync
方法的傳回值。 ShowAsync
方法會傳回 Task
物件,即是在未來要完成之工作的預留位置。 在我們的案例中,我們不需要等候工作完成,因此我們可以捨棄傳回值。
5. 執行應用程式
讓我們看看到目前為止已完成的部分! 按 F5 或 Ctrl-F5 來執行應用程式。 輸入您的名稱,選取 [Submit] \(提交\) 按鈕,應該會顯示問候您的對話方塊。
6. 實作 IsNameNeeded
屬性
如果您關閉對話方塊,系統仍然會顯示 UI 的名稱輸入部分。 這不是我們想要的效果。 我們需要在使用者成功填寫表單後隱藏表單。 讓我們在下一個步驟中使用資料繫結來執行此操作。
開啟 MainPage.xaml.cs,然後建立屬性以指出是否仍然需要輸入使用者的名稱。 在 MainPage
類別內新增下列程式碼:
private bool _isNameNeeded = true;
public bool IsNameNeeded
{
get { return _isNameNeeded; }
set
{
if (value != _isNameNeeded)
{
_isNameNeeded = value;
PropertyChanged?.Invoke(
this, new PropertyChangedEventArgs(nameof(IsNameNeeded)));
}
}
}
在到達 setter 之前,這是個具有支援欄位和 true
預設值的標準布林值屬性。 屬性 setter 會先確認新值是否與舊值相同。 如果相同,便不需要執行任何動作。 在沒有任何變更的情況下,您便不應該進行重新計算配置及重新呈現控制項的冗長程序。 不過,如果屬性的值「已經」變更,我們就必須使用 PropertyChanged
事件來告訴 UI 該狀況。
在上述程式碼中,您可以看到 INotifyPropertyChanged 介面的標準模式:
- 請確認值是否已經變更。
- 如果已變更,則設定新值。
- 請通知 UI。
在通知 UI (假設繫結模式已設為 OneWay
或 TwoWay
) 之後,它會呼叫屬性的 getter,接收新值,然後相應地變更 UI。
7. 在使用者選取 [Submit] (提交) 按鈕後隱藏表單
在我們的案例中,我們想要讓名稱輸入表單只在使用者選取 [Submit] \(提交\) 按鈕前顯示。 然後它應該在顯示問候訊息時消失。 讓我們透過在開頭新增此程式碼來變更 OnSubmitClicked
方法:
if (string.IsNullOrEmpty(UserName))
{
return;
}
IsNameNeeded = false;
首先,系統會執行快速檢查,因為這裡我們已不再接受空白使用者名稱。 輸入名稱之後,IsNameNeeded
會被設定為 false
,且應用程式會接著顯示訊息對話方塊。 設定 IsNameNeeded
的值會引發 NotifyPropertyChanged
事件並通知 UI。
我們現在已完成用以隱藏 UI 的程式碼。 讓我們回到 XAML!
在 XAML 端,我們需要在 IsNameNeeded
為 False 時隱藏 TextBlock
、TextBox
與 Button
。 或者,我們可以直接透過單一步驟隱藏其容器,StackPanel
。 只需將 Visibility
屬性新增至 StackPanel
即可,像這樣:
Visibility="{x:Bind IsNameNeeded, Mode=OneWay}"
執行應用程式,在 TextBox
中輸入您的名稱,然後確認輸入表單在您選取 [Submit] \(提交\) 按鈕時會確實消失。
8. 使用 UI 對 UI 繫結來顯示問候語
讓我們將 MessageDialog
取代為更永久性的顯示項目:一個位於左上角的 TextBlock
。 將一個新的 TextBlock
新增至 XAML 中的主要 Grid
控制項。
<TextBlock Text="{x:Bind sys:String.Format('Hello {0}!', tbUserName.Text), Mode=OneWay}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="10"/>
這裡有許多新項目正在進行。 讓我們仔細分析 Text
屬性的繫結!
為了評估 TextBlock
上 Text
屬性的值,系統會以格式字串 "Hello {0}"
呼叫內建的 String.Format
方法。 要格式化的物件將是 tbUserName.Text
(亦即 tbUserName
控制項上的 Text
)。 繫結的模式定義為 OneWay
,表示 TextBlock
將從 TextBox
的 Text
屬性接收資料。
這稱為「UI 對 UI 繫結」,因為資料繫結的來源和目標都在 UI 上。 若要查看其實際運作情況,您必須定義 sys
命名空間 (包含 System.Format
方法)。 將下列程式碼行新增至 XAML 中的根 Page
標籤:
xmlns:sys="using:System"
現在,如果您執行應用程式,就會看到每次按下按鍵時,問候語都會更新。 您甚至不需要將焦點從 TextBox
移開,或是選取 [Submit] \(提交\) 按鈕!
在真實世界的應用程式中,並不會透過 UI 對 UI 繫結顯示使用者的名稱。 您應該會繫結至 User
類別的 DisplayName
屬性或類似項目。
9. 隱藏問候語直到使用者選取 [提交] 為止
雖然在輸入時就更新問候語看起來很酷炫,但一開始出現的「Hello !」文字可能會看起來不專業。 建議讓問候語 TextBlock
保持隱藏,直到使用者選取 [提交] 按鈕後再顯示。
若要計算出是否要顯示問候語,請使用名為 GetGreetingVisibility
的方法,然後將它新增至 MainPage
類別。
public Visibility GetGreetingVisibility()
{
return IsNameNeeded ? Visibility.Collapsed : Visibility.Visible;
}
您可能已注意到,當隱藏 StackPanel
時,我們是將 bool
值繫結至 Visibility
屬性 (其具有 UIElement.Visibility
的類型)。 將 Visibility
繫結至 bool
值的情況是如此常見,以致 Microsoft 在兩者間建立了預設轉換,這就是為何我們先前沒有收到任何類型轉換錯誤的原因。 不過,這個自動轉換只適用於屬性,因此 GetGreetingVisibility()
方法必須傳回 UIElement.Visibility
,而不是布林值。
由於是搭配屬性,因此當我們希望 UI 重新評估該方法時,必須使用 PropertyChanged
事件來通知 UI。 因此,讓我們在 OnSubmitClicked
方法的結尾新增這一行。
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(GetGreetingVisibility)));
作為最後一步,我們必須將 Visibility
屬性新增至問候語 TextBlock
來實際執行繫結。 在 MainPage.xaml 中,編輯 TextBlock
,使其看來像這樣:
<TextBlock Text="{x:Bind sys:String.Format('Hello {0}!', tbUserName.Text), Mode=OneWay}"
Visibility="{x:Bind GetGreetingVisibility(), Mode=OneWay}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="10"/>
請注意,我們不必為 GetGreetingVisibility()
呼叫新增任何命名空間參考,因為它本身是 MainPage
類別的成員。
最後,若要停止顯示 MessageDialog
,請從 OnSubmitClicked
方法將下列行註解化。
// var dlg = new Windows.UI.Popups.MessageDialog($"Hello {UserName}!");
// dlg.ShowAsync();
現在您已準備就緒,可以執行應用程式並享有您的問候訊息。
摘要
在此課程中,您已了解資料繫結如何讓 UI 與您程式碼間或讓兩個 UI 間的資料傳輸變得更容易。 不過,要撰寫的連接程式碼為數眾多,尤其是在屬性 setter 中叫用 PropertyChanged
事件時。 在下一課中,您將建立一個協助程式類別,以簡化 INotifyPropertyChanged
模式的使用。
在此課程中,我們會探索如何使用資料繫結來進行資料輸入,根據應用程式的狀態來顯示和隱藏某些 UI 區段。 您也會熟悉完整的 INotifyPropertyChanged
模式,並深入了解 DataContext
。
讓我們使用看起來如下的親切問候語來擴充現有的示範。
當您選取 [提交] 按鈕時,應用程式將會在頂端顯示一個簡單的問候語。
1. 建立與視窗同寬的 DataContext
如果您未在 Visual Studio 中開啟進行上一課時所建立的專案,請立即開啟。
在上一個課程中,我們已建立專用的 Clock
類別,且此類別已在顯示時鐘的 TextBlock
內具現化。 此 Clock
類別包含時鐘本身的商務邏輯。 不過,您通常必須因某些原因包含更多功能,而在 UI 上為每個單一控制項設定 DataContext
將非常乏味。
幸運的是,DataContext
的設計可套用到整個 XAML 樹狀結構 (或只套用到樹狀結構中的某個部分)。 DataContext
的一個重要屬性是它在整個 XAML 樹狀結構中繼承,您可以針對特定子樹狀結構覆寫它。
讓我們看看這在實務上如何運作。 建立名為 MainWindowDataContext
的新類別,並確定類別及其建構函式是公用的:
namespace DatabindingSampleWPF
{
public class MainWindowDataContext
{
public MainWindowDataContext()
{
}
}
}
現在,針對整個 Window
,將此類別的執行個體設定為 DataContext
。 在 MainWindow.xaml 中,在開頭 Window
標記正後方新增此項目:
<Window.DataContext>
<local:MainWindowDataContext />
</Window.DataContext>
這時,Visual Studio 可能會指出不存在 DatabindingSampleWPF.MainWindowDataContext
類別。 這是因為自您新增此類別之後,並未編譯專案。 您可以透過組建專案來修正此錯誤。
讓我們複習截至目前為止已討論的內容。 DataContext
是設定於 Window
(根) 層級。 此物件執行個體將會是 DataContext
內每個控制項的 Window
。 唯一的例外是顯示時鐘的 TextBlock
,它已設定自己的 DataContext
,因此會覆寫繼承的全域 DataContext
。 若此 TextBlock
在階層中有進一步的控制項,那些控制項也會繼承在 TextBlock
的 DataContext
上設定的 Clock
物件。
2. 建立資料輸入 UI
資料輸入 UI 相當簡單:只是在畫面中間以單一水平配置顯示一個 TextBlock
、一個 TextBox
,以及一個 Button
。 以水平方式放置控制項最簡單的方法,是使用 StackPanel
,像這樣。
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock Margin="10"
VerticalAlignment="Center"
Text="Enter your name:"/>
<TextBox Name="tbName"
Margin="10"
Width="150"
VerticalAlignment="Center"/>
<Button Margin="10"
VerticalAlignment="Center">Submit</Button>
</StackPanel>
請複製上述程式碼,並將它貼到 MainPage.xaml 的 Grid
標籤內,位於時鐘的 TextBlock
底下。
3. 實作並繫結 UserName 屬性
讓我們將注意力轉向程式碼。 開啟 MainWindowDataContext.cs
,然後建立名為 UserName
的新屬性。
public string? UserName { get; set; }
回到 MainWindow.xaml
之後,我們可以在 UserName
屬性與 TextBox
控制項之間建立資料繫結。 新增 Text
屬性來變更 TextBox
控制項,像這樣:
<TextBox Name="tbUserName"
Margin="10"
Width="150"
VerticalAlignment="Center"
Text="{Binding UserName, Mode=TwoWay}"/>
注意
在這裡,請勿混淆 TextBlock
與 TextBox
控制項。 它們在 XAML 中看起來非常相似,但如果您將 UserName
繫結至 TextBlock
的文字屬性而不是 TextBox
,則應用程式將無法運作。
透過上述程式碼,我們已在 TextBox
的 Text
屬性與程式碼中的 UserName
屬性之間建立雙向繫結。 這意謂著每當使用者輸入文字 (並將焦點從 TextBox
移開) 時,程式碼中的 UserName
屬性都會變更。 此外,TextBox
的文字將會在應用程式啟動時,或每當我們以 propertyName
參數 "UserName"
引發 NotifyPropertyChanged
事件時,設定成 UserName
中儲存的值。 (我們不會在此課程中這麼做)。
注意
在 WPF 中,會自動為大部分的常見情況決定繫結模式。 例如,若您要繫結到 TextBox
的 Text
屬性,WPF 預設會將繫結模式設定為 TwoWay
。 這表示我們甚至可以略過這裡的指定繫結模式步驟,並只撰寫 Text={Binding UserName}
。 您可以在這裡 \(機器翻譯\) 深入了解繫結模式。
4. 建立 [Submit] (提交) 按鈕的 Click 處理常式
接著,在設計介面上,按兩下 [Submit] \(提交\) 按鈕。 這會自動在 MainWindow.xaml.cs
中建立 Button_Click
事件並開啟檔案。 Button_Click
不是非常描述性的名稱,因此請將方法的名稱變更為 OnSubmitClicked
。 在您完成輸入之後,請按一下 OnSubmitClicked
行旁邊的螺絲起子提示,然後從功能表中選取 [將 'Button_Clicked' 重新命名為 'OnSubmitClicked']。 回到 XAML,並確認按鈕的 XAML 現在看起來像這樣:
<Button Margin="10"
VerticalAlignment="Center"
Click="OnSubmitClicked">Submit</Button>
回到程式碼後置之後,讓我們在使用者按下按鈕時顯示簡單的對話方塊。 將便利屬性新增到 MainWindow
類別的頂端,以便我們可以輕鬆地存取設定為整個 MainWindow
之 DataContext
的 MainWindowDataContext
物件。
private MainWindowDataContext DC => (MainWindowDataContext)DataContext;
接下來,將下列程式碼新增至 OnSubmitClicked
方法:
MessageBox.Show($"Hello {DC.UserName}!");
在 TextBox
中輸入的文字值會儲存在 MainWindowDataContext.UserName
屬性中。 第一行會將對 MainWindowDataContext
物件的參考儲存在暫存變數中。 第二行會顯示包含問候訊息的訊息方塊。
如果您不熟悉 $"Hello {Username}"
語法,它相當於 "Hello " + UserName + "!"
或 String.Format("Hello {0}!", UserName)
。 這個更為精簡且易讀的語法被稱為字串內插補點,並已在 C# 6 中導入。
5. 執行應用程式
讓我們試用我們到目前為止所做的工作! 按 F5 或 Ctrl-F5 來執行應用程式。 輸入您的名稱,選取 [Submit] \(提交\) 按鈕,應該會顯示問候您的對話方塊。
6. 實作 IsNameNeeded
屬性
留意到在按下 [Submit] \(提交\) 按鈕之後,UI 的名稱輸入部分仍未消失。 我們需要在使用者成功填寫表單後隱藏它。 讓我們在下一個步驟中使用資料繫結來執行此操作。
首先,請開啟 MainWindowDataContext.cs,然後使 MainWindowDataContext
繼承自 INotifyPropertyChanged
,和我們針對 Clock
類別所作的相同。
using System.ComponentModel;
public class MainWindowDataContext : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
接著,建立屬性以指出是否仍然需要輸入使用者的名稱。 在 MainWindowDataContext
類別內新增下列程式碼:
private bool _isNameNeeded = true;
public bool IsNameNeeded
{
get { return _isNameNeeded; }
set
{
if (value != _isNameNeeded)
{
_isNameNeeded = value;
PropertyChanged?.Invoke(
this, new PropertyChangedEventArgs(nameof(IsNameNeeded)));
}
}
}
在到達 setter 之前,這是個具有支援欄位和 true
預設值的標準布林值屬性。 屬性 setter 會先確認新值是否與舊值相同。 如果相同,便不需要執行任何動作。 在沒有任何變更的情況下,您便不應該進行重新計算配置及重新呈現控制項的冗長程序。 不過,如果屬性的值「已經」變更,我們就必須使用 PropertyChanged
事件來告訴 UI 該狀況。
在上述程式碼中,您可以看到 INotifyPropertyChanged 介面的標準模式:
- 請確認值是否已經變更。
- 如果已變更,則設定新值。
- 請通知 UI。
在通知 UI (假設繫結模式已設為 OneWay
或 TwoWay
) 之後,它會呼叫屬性的 getter,接收新值,然後相應地變更 UI。
7. 在使用者選取 [Submit] (提交) 按鈕後隱藏表單
在我們的案例中,我們想要讓名稱輸入表單只在使用者選取 [Submit] \(提交\) 按鈕前顯示。 然後它應該在顯示問候訊息時消失。 讓我們透過在開頭新增此程式碼來變更 OnSubmitClicked
方法:
if (string.IsNullOrWhiteSpace(DC.UserName))
{
return;
}
DC.IsNameNeeded = false;
首先,系統會執行快速檢查,因為這裡我們已不再接受空白使用者名稱。 輸入名稱之後,IsNameNeeded
會被設定為 false
,且應用程式會接著顯示訊息對話方塊。 設定 IsNameNeeded
的值會引發 NotifyPropertyChanged
事件並通知 UI。
我們現在已完成用以隱藏 UI 的程式碼。 讓我們回到 XAML!
在 XAML 端,我們需要在 IsNameNeeded
為 False 時隱藏 TextBlock
、TextBox
與 Button
。 或者,我們可以直接透過單一步驟隱藏其容器,StackPanel
。 將 Visibility
屬性新增至 StackPanel
,像這樣:
Visibility="{Binding IsNameNeeded, Converter={StaticResource BooleanToVisibilityConverter}}"
此繫結由兩個部分組成。 第一個部分指定繫結路徑,它指向設定為整個 Window
之 DataContext
的 MainWindowDataContext
物件的 IsNameNeeded
屬性。
但是 IsNameNeeded
屬性是布林值,而 Visibility
的類型則是 System.Windows.Visibility \(機器翻譯\),其為 enum
。 我們必須在兩者之間執行轉換。 這樣的轉換很常見,且 WPF 有名為 BooleanToVisibilityConverter
的內建協助程式類別。 我們必須建立此類別的執行個體,並從繫結宣告參照它。
我們會在 XAML 中具現化此類別,作為 Window
物件的資源。 每個 FrameworkElement
都可以有自己的資源集合,而且具有識別集合中每個資源的索引鍵。 上述繫結中的 BooleanToVisibilityConverter
就是此索引鍵,它會指向資源集合內的 BooleanToVisibilityConverter
物件。 您可以透過新增下列程式碼至 Window
開頭標記的正後方來定義資源集合:
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>
執行應用程式,在 TextBox
中輸入您的名稱,然後確認輸入表單在您選取 [Submit] \(提交\) 按鈕時會確實消失。
8. 使用 UI 對 UI 繫結來顯示問候語
讓我們將 MessageDialog
取代為更永久性的顯示項目:一個位於左上角的 TextBlock
。 將一個新的 TextBlock
新增至 XAML 中的主要 Grid
控制項。
<TextBlock Text="{Binding Text, ElementName=tbName, StringFormat='Hello {0}!'}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="10"/>
這個新的 TextBlock
中引進了數個新內容。 讓我們仔細分析 Text
屬性的繫結!
為了評估 TextBlock
上 Text
屬性的值,系統會以格式字串 "Hello {0}"
呼叫內建的 String.Format 方法。 要格式化的物件將是 tbName.Text
(亦即 tbName
控制項上的 Text
)。 繫結的模式自動定義為 OneWay
,表示 TextBlock
將從 TextBox
的 Text
屬性接收資料。
這稱為「UI 對 UI 繫結」,因為資料繫結的來源和目標都在 UI 上。 若要以動作呈現,只要執行應用程式。 請注意與每個按鍵動作更新問候語的方式。 您甚至不需要將焦點從 TextBox
移開,或是選取 [Submit] \(提交\) 按鈕!
在真實世界的應用程式中,並不會透過 UI 對 UI 繫結顯示使用者的名稱。 您應該會繫結至 User
類別的 DisplayName
屬性或類似項目,或其他類似方法。
9. 隱藏問候語直到使用者選取 [提交] 為止
雖然在輸入時就更新問候語看起來很酷炫,但一開始出現的「Hello !」文字可能會看起來不專業。 建議讓問候語 TextBlock
保持隱藏,直到使用者選取 [提交] 按鈕後再顯示。
若要計算出是否要顯示問候語,請使用名為 GreetingVisibility
的屬性,然後將它新增至 MainWindowDataContext
類別。
public Visibility GreetingVisibility => IsNameNeeded ? Visibility.Collapsed : Visibility.Visible;
您也必須將 System.Windows
命名空間新增至 MainWindowDataContext
中的 using
。
您可能還記得之前當我們隱藏 StackPanel
時,我們是將 bool
值繫結至 Visibility
屬性 (其具有 System.Windows.Visibility
的類型)。 不過,如果繫結來源已經是正確的資料類型,我們便可以略過 BooleanToVisibilityConverter
。
如同以往,當我們希望 UI 重新評估 GreetingVisibility
時,必須使用 PropertyChanged
事件來通知 UI。 因此,讓我們將這一行加入到 IsNameNeeded
setter 中 if
區塊的結尾。
PropertyChanged?.Invoke(
this, new PropertyChangedEventArgs(nameof(GreetingVisibility)));
這可確保每當變更 IsNameNeeded
時,就會引發兩個 PropertyChanged
事件:一個用於 IsNameNeeded
屬性本身,而另一個用於計算屬性 GreetingVisibility
(取決於 IsNameNeeded
)。
作為最後一步,將 Visibility
屬性新增至問候語 TextBlock
來實際執行繫結。 在 MainWindow.xaml
中,編輯 TextBlock
,使其如下所示:
<TextBlock Text="{Binding Text, ElementName=tbName, StringFormat='Hello {0}!'}"
Visibility="{Binding GreetingVisibility}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="10"/>
最後,若要停止顯示 MessageBox
,請從 MainWindow.xaml.cs
中的 OnSubmitClicked
方法將下列行註解化。
// MessageBox.Show($"Hello {DC.UserName}!");
現在您已準備就緒,可以執行應用程式並享有您的問候訊息。
摘要
在此課程中,您已了解資料繫結如何讓 UI 與您程式碼間或讓兩個 UI 間的資料傳輸變得更容易。 不過,要撰寫的連接程式碼為數眾多,尤其是在屬性 setter 中叫用 PropertyChanged
事件時。 在下一課中,您將建立一個協助程式類別,以簡化 INotifyPropertyChanged
模式的使用。