第 16 章的摘要。 資料繫結
注意
這本書於2016年春季出版,此後一直沒有更新。 這本書中有很多仍然有價值,但一些材料已經過時,有些主題不再完全正確或完整。
程序設計人員通常會發現自己撰寫事件處理程式,以偵測某個物件的屬性何時變更,並使用該處理程式來變更另一個物件中的屬性值。 此程式可以透過數據系結的技術來自動化。 數據系結通常會在 XAML 中定義,並成為使用者介面定義的一部分。
這些數據系結通常會將使用者介面對象連接到基礎數據。 這是在第 18 章中 進一步探索的技術。MVVM。 不過,數據系結也可以連接兩個或多個使用者介面元素。 本章中大部分的早期數據系結範例都示範這項技術。
系結基本概念
資料係結涉及數個屬性、方法和類別:
- 類別
Binding
衍生自BindingBase
並封裝數據系結的許多特性 - 屬性
BindingContext
是由BindableObject
類別所定義 - 方法
SetBinding
也會由BindableObject
類別定義 - 類別
BindableObjectExtensions
會定義三個額外的SetBinding
方法
下列兩個類別支援系結的 XAML 標記延伸:
BindingExtension
Binding
支援標記延伸ReferenceExtension
x:Reference
支援標記延伸
資料系結涉及兩個介面:
INotifyPropertyChanged
在命名空間中System.ComponentModel
是用於在屬性變更時實作通知IValueConverter
用來定義小型類別,將值從某個類型轉換成數據系結中的另一個類型
數據系結會連接相同物件的兩個屬性,或更常見的是兩個不同的物件。 這兩個屬性稱為 來源 和 目標。 一般而言,來源屬性的變更會導致目標屬性發生變更,但有時方向會反轉。 無論:
- 目標屬性必須由支援
BindableProperty
- 來源屬性通常為實作之類別的成員
INotifyPropertyChanged
實作 INotifyPropertyChanged
的類別會在屬性變更值時引發 PropertyChanged
事件。 BindableObject
當屬性支援變更值時,會實作 INotifyPropertyChanged
並自動引發PropertyChanged
事件,但您可以撰寫自己的類別,INotifyPropertyChanged
而實作而不衍生自 BindableObject
。BindableProperty
程式代碼和 XAML
OpacityBindingCode 範例示範如何在程式代碼中設定資料系結:
- 來源是
Value
的屬性Slider
- 目標是
Opacity
的屬性Label
這兩個物件會藉由將 對象的 設定BindingContext
Label
為 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
屬性SearchBar
DatePicker
的Date
屬性TimePicker
的Time
屬性
BindingModes 範例會示範具有數據系結的四種系結模式,其中目標為 FontSize
的屬性Label
,而來源是 Value
的Slider
屬性。 這可讓每個 Slider
控件對應 Label
的字型大小。 但是專案 Slider
不會初始化,因為 DefaultBindingMode
屬性的 FontSize
是 OneWay
。
ReverseBinding 範例會在參考每個 之 屬性的 Slider
屬性上Value
設定系結。Label
FontSize
這看起來是回溯的,但它在初始化 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
、FontAttributes
FontSize
、 和 IsChecked
屬性,但控件的視覺效果完全沒有邏輯。
相反地,檔案 NewCheckBox.cs.xaml
會根據程式代碼後置檔案中定義的屬性,透過專案上的數據系結 Label
,包含控件視覺效果的所有標記。
NewCheckBoxDemo 範例示範NewCheckBox
自定義控件。