在 XAML 中使用資料繫結
資料繫結可以在程式碼中或使用標記延伸在 XAML 中宣告。 本單元會討論後者,因為它是建立繫結最常見的方式。 有幾個偏好使用 XAML 的原因。 第一,大多數的人都將繫結視為其 UI 程式碼的一部分,因為繫結會取得資料以供 UI 顯示。 第二,有一個名為 Binding
的標記延伸讓此做法更輕鬆。
什麼是資料繫結
「繫結」會將兩個屬性繫結在一起。 一個屬性會在您的 UI 中,另一個在您的資料模型物件中。 如果其中一個屬性的值發生變更,繫結物件便可更新另一個屬性。 換句話說,繫結是會同步處理您的 UI 與資料的中繼物件。 我們使用「來源」和「目標」這兩個詞來識別所涉及的兩個物件:
來源:來源可以是任何類型的物件。 在實務上,您通常會使用資料物件作為您的來源。 您將必須識別該來源物件上要參與繫結的屬性。 您可在繫結中設定
Path
屬性來識別該屬性。目標:目標是使用稱為
BindableProperty
的特殊屬性實作的屬性。 具有BindableProperty
的物件必須衍生自BindableObject
。 .NET MAUI 中提供的所有控制項都衍生自BindableObject
,而且其大部分屬性都是BindableProperties
。
下圖說明繫結如何成為兩個屬性之間的中間物件:
如何在 XAML 中建立資料繫結
讓我們看看一個使用 {Binding}
標記延伸在 XAML 中建立的簡單繫結。 它將來源的 WeatherService.Humidity
屬性繫結至 UI 控制項的 Text
屬性。
<VerticalStackLayout Margin="10">
<VerticalStackLayout.Resources>
<ResourceDictionary>
<services:WeatherService x:Key="myWeatherService" />
</ResourceDictionary>
</VerticalStackLayout.Resources>
<Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
</VerticalStackLayout>
繫結來源為:
WeatherService
類型的物件執行個體。 執行個體會透過{StaticResource ...}
XAML 延伸來參考,該延伸指向堆疊配置資源字典中的物件。Path
指向WeatherService
類型上名為Humidity
的屬性。Path
是{Binding}
語法上的第一個未命名參數,而且可以省略Path=
語法。 這兩個繫結相等:<Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" /> <Label Text="{Binding Humidity, Source={StaticResource myWeatherService}}" />
繫結目標為:
Label
控制項。- 該控制項的
Text
屬性。
顯示 UI 時,{Binding}
XAML 延伸會在 WeatherService
與 Label
之間建立一個繫結。 該繫結會將 WeatherService.Humidity
屬性的值讀入 Label.Text
屬性。
使用另一個控制項作為繫結來源
繫結的其中一個實用功能是能夠繫結至其他控制項。 下列 XAML 是簡單的示範:
<VerticalStackLayout HorizontalOptions="Center" VerticalOptions="Center">
<Label x:Name="TargetLabel" Text="TEXT TO ROTATE" BackgroundColor="Yellow" />
<Slider WidthRequest="100" Maximum="360"
Value="{Binding Rotation, Mode=OneWayToSource, Source={x:Reference TargetLabel}}" />
</VerticalStackLayout>
Slider.Value
屬性會繫結至 Label.Rotation
屬性,但使用的方式與先前所說明的不同。 此屬性使用的是繫結模式 OneWayToSource
,它顛倒了一般的繫結機制。 當目標變更時,OneWayToSource
會更新來源,而不是來源更新目標。 在此範例中,當滑桿移動時,它會根據滑桿的值更新標籤的旋轉,如下列的動畫所示:
將控制項相互繫結的一般場景是當某個控制項 (通常是集合控制項,例如 ListView
或 CarouselView
) 具有您要用作資料來源的選定項目時。 在顯示天氣預報的頁面範例中,您可能會有一個呈現五天預報的 ListView
。 當使用者在清單中選取某一天時,該天氣預報的詳細資訊會顯示在其他控制項中。 如果使用者選取另一天,其他控制項會再次使用所選日子的詳細資料進行更新。
跨多個繫結使用相同的來源
上述範例示範如何使用靜態資源作為單一繫結的來源。 該來源可用於多個繫結。 以下是宣告跨三個不同控制項的繫結的範例,所有控制項都繫結到同一物件和屬性 Path
(儘管有些控制項省略了 Path
屬性):
<VerticalStackLayout Margin="10">
<VerticalStackLayout.Resources>
<vm:SimpleWeatherServiceObject x:Key="myWeatherService" />
</VerticalStackLayout.Resources>
<Entry Text="{Binding Humidity, Source={StaticResource myWeatherService}}" />
<Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
</VerticalStackLayout>
使用相同的 Source
時,您不需要使用相同的 Path
:
<VerticalStackLayout Margin="10">
<VerticalStackLayout.Resources>
<vm:SimpleWeatherServiceObject x:Key="myWeatherService" />
</VerticalStackLayout.Resources>
<Entry Text="{Binding Temperature, Source={StaticResource myWeatherService}}" />
<Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
</VerticalStackLayout>
您很少會呈現某一個來源中的單一資料片段 (儘管有可能會發生)。 通常,您有數個控制項使用來自同一個來源的不同資料。 這種情況非常常見,以至於 BindableObject
類別有一個名為 BindingContext
的屬性,該屬性用作資料繫結的來源。 請記住,.NET MAUI 控制項繼承自 BindableObject
類別,因此 .NET MAUI 控制項具有 BindingContext
屬性。
設定繫結的 Source
是選擇性的。 未設定 Source
的繫結會自動在 XAML 視覺化樹狀結構中搜尋 BindingContext
,它會在 XAML 中設定或透過程式碼指派給父元素。 該繫結會遵循下列模式進行評估:
如果該繫結定義了
Source
,則會使用該來源並停止搜尋。 該繫結的Path
會套用至Source
以取得值。 如果未設定Source
,則會開始搜尋繫結來源。搜尋會從目標物件本身開始。 如果目標物件的
BindingContext
不是 Null,則搜尋會停止,並將該繫結的Path
套用至BindingContext
以取得值。 如果BindingContext
為 Null,則搜尋會繼續進行。這個過程會持續進行,直到它達到 XAML 的根部。 搜尋會透過檢查根部的
BindingContext
是否為非 Null 值來結束。 如果找不到有效的BindingContext
,則該繫結沒有任何可繫結的項目,且不會執行任何動作。
通常會在根物件層級設定 BindingContext
,以套用至整個 XAML。
最後還有一個方便的功能值得一提。 繫結會監看是否有對其來源之「物件參考」的變更。 它甚至對使用 BindingContext
作為其來源的繫結也有效。 如果 Source
或 BindingContext
被重新指派給另一個物件,繫結就會從新來源抓取資料並更新其目標。