在 XAML 中使用資料繫結
- 6 分鐘
您可以使用標記延伸,在程式碼或 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指向Humidity類型上名為WeatherService的屬性。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變更時,會更新來源。 在此範例中,當滑桿移動時,它會根據滑桿的值更新標籤的旋轉,如下列的動畫所示:
將控件系結至另一個控件的一般情況是,當一個控件—通常是如 CollectionView 或 CarouselView 之類的集合控件—具有您想要作為數據來源使用的選取項目時。 在顯示天氣預報的頁面範例中,CollectionView 可能會呈現五天的天氣預報。 當使用者在清單中選取某一天時,該天氣預報的詳細資訊會顯示在其他控制項中。 如果使用者選取另一天,其他控制項會再次使用所選日子的詳細資料進行更新。
備註
在 .NET MAUI 10 中, ListView 已被棄用,改為 CollectionView。 用於 CollectionView 在新應用程式中顯示資料清單。
跨多個繫結使用相同的來源
上述範例示範如何使用靜態資源作為單一繫結的來源。 該來源可用於多個繫結。 以下是宣告跨三個不同控制項的繫結的範例,所有控制項都繫結到同一物件和屬性 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>
使用相同的 Path 時,您不需要使用相同的 Source:
<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 被重新指派給另一個物件,繫結就會從新來源抓取資料並更新其目標。