注意
這本書於2016年春季出版,此後一直沒有更新。 這本書中有很多仍然有價值,但一些材料已經過時,有些主題不再完全正確或完整。
程序設計人員通常會發現自己撰寫事件處理程式,以偵測某個物件的屬性何時變更,並使用該處理程式來變更另一個物件中的屬性值。 此程式可以透過數據系結的技術來自動化。 數據系結通常會在 XAML 中定義,並成為使用者介面定義的一部分。
這些數據系結通常會將使用者介面對象連接到基礎數據。 這是在第 18 章中 進一步探索的技術。MVVM。 不過,數據系結也可以連接兩個或多個使用者介面元素。 本章中大部分的早期數據系結範例都示範這項技術。
系結基本概念
資料係結涉及數個屬性、方法和類別:
- 類別
Binding衍生自BindingBase並封裝數據系結的許多特性 - 屬性
BindingContext是由BindableObject類別所定義 - 方法
SetBinding也會由BindableObject類別定義 - 類別
BindableObjectExtensions會定義三個額外的SetBinding方法
下列兩個類別支援系結的 XAML 標記延伸:
BindingExtensionBinding支援標記延伸ReferenceExtensionx:Reference支援標記延伸
資料系結涉及兩個介面:
INotifyPropertyChanged在命名空間中System.ComponentModel是用於在屬性變更時實作通知IValueConverter用來定義小型類別,將值從某個類型轉換成數據系結中的另一個類型
數據系結會連接相同物件的兩個屬性,或更常見的是兩個不同的物件。 這兩個屬性稱為 來源 和 目標。 一般而言,來源屬性的變更會導致目標屬性發生變更,但有時方向會反轉。 無論:
- 目標屬性必須由支援
BindableProperty - 來源屬性通常為實作之類別的成員
INotifyPropertyChanged
實作 INotifyPropertyChanged 的類別會在屬性變更值時引發 PropertyChanged 事件。 BindableObject當屬性支援變更值時,會實作 INotifyPropertyChanged 並自動引發PropertyChanged事件,但您可以撰寫自己的類別,INotifyPropertyChanged而實作而不衍生自 BindableObject。BindableProperty
程式代碼和 XAML
OpacityBindingCode 範例示範如何在程式代碼中設定資料系結:
- 來源是
Value的屬性Slider - 目標是
Opacity的屬性Label
這兩個物件會藉由將 對象的 設定BindingContextLabel為 Slider 對象來連接。 這兩個SetBinding屬性是藉由在參考OpacityProperty可系結屬性和Value以字串表示的 Slider 屬性上Label呼叫擴充方法來連接。
操作 時 Slider ,會導致 Label 淡入和淡出檢視。
OpacityBindingXaml 與 XAML 中的數據系結集是相同的程式。 BindingContext的 Label 會設定為x:Reference參考 的Slider標記延伸,而 Opacity 的 Label 屬性會設定為Binding標記延伸,其 Path 屬性會參考 Value 的Slider屬性。
Source 和 BindingContext
BindingSourceCode 範例會顯示程序代碼中的替代方法。 建立 Binding 物件的方式是將 Source 屬性設定為 Slider 物件,並將 Path 屬性設定為 「Value」。。 然後在 SetBinding 物件上Label呼叫的方法BindableObject。
建 Binding 構函式 也可以用來定義 Binding 物件。
BindingSourceXaml 範例會顯示 XAML 中的可比較技術。 的 Opacity Label 屬性會設定為 Binding 標記延伸,並 Path 設定為 Value 屬性,並 Source 設定為內嵌 x:Reference 標記延伸。
總而言之,有兩種方式可以參考系結來源物件:
BindingContext透過目標的屬性Source透過物件本身的Binding屬性
如果同時指定兩者,則第二個優先。 的優點 BindingContext 是它會透過可視化樹狀結構傳播。 如果多個目標屬性系結至相同的來源物件,這非常有用。
WebViewDemo 程式會使用 WebView 元素來示範這項技術。 回溯和向前巡覽的兩 Button 個元素繼承 BindingContext 自參考 的 WebView父代 。 然後,這 IsEnabled 兩個按鈕的屬性具有簡單的 Binding 標記延伸,以按鈕 IsEnabled 屬性為目標,根據 CanGoBack 的設定和 CanGoForward 只讀屬性 WebView。
系結模式
將 Mode 的 Binding 屬性設定為 列舉的成員 BindingMode :
OneWay如此一來,來源屬性中的變更會影響目標OneWayToSource因此,目標屬性中的變更會影響來源TwoWay讓來源和目標中的變更彼此受到影響Default以建立目標BindableProperty時使用DefaultBindingMode指定的 。 如果未指定任何專案,則預設值為OneWay一般可系結屬性,以及OneWayToSource唯讀可系結屬性。
注意
列舉 BindingMode 現在也包含 OnTime 只有在系結內容變更而不是來源屬性變更時套用系結。
可能是MVVM案例中資料系結目標的屬性通常具有 DefaultBindingMode 的 TwoWay。 這些包括:
Slider和Stepper的Value屬性Switch的IsToggled屬性Text、Editor和 的Entry屬性SearchBarDatePicker的Date屬性TimePicker的Time屬性
BindingModes 範例會示範具有數據系結的四種系結模式,其中目標為 FontSize 的屬性Label,而來源是 Value 的Slider屬性。 這可讓每個 Slider 控件對應 Label的字型大小。 但是專案 Slider 不會初始化,因為 DefaultBindingMode 屬性的 FontSize 是 OneWay。
ReverseBinding 範例會在參考每個 之 屬性的 Slider 屬性上Value設定系結。LabelFontSize 這看起來是回溯的,但它在初始化 Slider 元素時效果更好,因為 Value 的 Slider 屬性具有 DefaultBindingMode 的 TwoWay。
這類似於MVVM中定義系結的方式,而且您會經常使用這種類型的系結。
字串格式
當目標屬性的類型為 string時,您可以使用 StringFormat 所 BindingBase 定義的 屬性,將來源 string轉換成 。 將 StringFormat 屬性設定為 .NET 格式字串,以搭配靜態 String.Format 格式來顯示物件。 在標記延伸中使用這個格式化字串時,請以單引號括住它,因此不會誤認為內嵌標記延伸。
ShowViewValues 範例示範如何在 XAML 中使用StringFormat。
WhatSizeBindings 範例示範如何顯示具有 系結至 Width 和 Height 屬性ContentPage的頁面大小。
為什麼它稱為「路徑」?
的 Path 屬性 Binding 稱為 ,因為它可以是以句點分隔的一系列屬性和索引器。 BindingPathDemos 範例會顯示數個範例。
系結值轉換器
當系結的來源和目標屬性是不同的類型時,您可以使用系結轉換器在類型之間轉換。 這是實作 介面並包含兩種方法的 IValueConverter 類別: Convert 將來源轉換成目標,以及 ConvertBack 將目標轉換成來源。
Book.Toolkit 連結庫中的 Xamarin.Forms類別是將 轉換成 int 的bool範例。IntToBoolConverter 其示範方式是 ButtonEnabler 範例,只有在至少輸入一個字元時Entry,才會啟用 Button 。
類別 BoolToStringConverter 會將 bool 轉換成 ,並定義兩個 string 屬性,以指定要針對 false 和 true 值傳回哪些文字。
BoolToColorConverter很類似。 SwitchText 範例示範如何使用這兩個Switch轉換器,根據設定以不同色彩顯示不同的文字。
泛型 BoolToObjectConverter 可以取代 BoolToStringConverter 和 BoolToColorConverter ,並做為任何類型的一般化 bool對對物件轉換器。
系結和自定義檢視
您可以使用資料系結來簡化自訂控制項。 程式NewCheckBox.cs代碼檔案會Text定義、、TextColor、FontAttributesFontSize、 和 IsChecked 屬性,但控件的視覺效果完全沒有邏輯。
相反地,檔案 NewCheckBox.cs.xaml 會根據程式代碼後置檔案中定義的屬性,透過專案上的數據系結 Label ,包含控件視覺效果的所有標記。
NewCheckBoxDemo 範例示範NewCheckBox自定義控件。
