基本系結
.NET 多平臺應用程式 UI (.NET MAUI) 數據系結會連結兩個對象之間的一組屬性,其中至少一個通常是使用者介面物件。 這兩個物件稱為「目標」和「來源」:
- 「目標」是資料繫結設定所在的物件 (和屬性)。
- 「來源」是資料繫結參考的物件 (和屬性)。
在最簡單的情況下,資料會從來源流向目標,這表示目標屬性值會從來源屬性值設定。 不過,在某些情況下,資料可能會從目標流向來源,或是雙向流動。
重要
即使數據系結提供數據,而不是接收數據,目標一律是數據系結所設定的物件。
具有系結內容的系結
請考慮下列 XAML 範例,其意圖是藉由操作 Slider來旋轉 Label :
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingDemos.BasicCodeBindingPage"
Title="Basic Code Binding">
<StackLayout Padding="10, 0">
<Label x:Name="label"
Text="TEXT"
FontSize="48"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Slider x:Name="slider"
Maximum="360"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
如果沒有資料繫結,您會將 Slider 的 ValueChanged
事件設定為事件處理常式,以存取 Slider 的 Value
屬性,並將該值設定為 Label 的 Rotation
屬性。 數據系結會自動執行這項工作,因此不再需要事件處理程式和其中的程序代碼。
您可以在衍生自 BindableObject 的任何類別執行個體上設定繫結,其中包括 Element、VisualElement、View 和 View 衍生項目。 繫結一律會在目標物件上設定。 繫結會參考來源物件。 若要設定資料繫結,請使用目標類別的下列兩個成員:
BindingContext
屬性指定來源物件。SetBinding
方法指定目標屬性和來源屬性。
在此範例中,Label 是繫結目標,而 Slider 是繫結來源。 Slider 來源中的變更會影響 Label 目標的旋轉。 資料會從來源流向目標。
BindableObject 所定義的 SetBinding
方法具有 BindingBase
類型的引數,而 Binding
類別衍生自該處,但有 BindableObjectExtensions
類別定義的其他 SetBinding
方法。 XAML 的程式代碼後置會從 類別使用更簡單 SetBinding
的擴充方法 BindableObjectExtensions
:
public partial class BasicCodeBindingPage : ContentPage
{
public BasicCodeBindingPage()
{
InitializeComponent();
label.BindingContext = slider;
label.SetBinding(Label.RotationProperty, "Value");
}
}
Label 物件是繫結目標,因此它是這個屬性設定所在的物件,也是對其呼叫方法的物件。 BindingContext
屬性指出繫結來源,也就是 Slider。 SetBinding
方法在繫結目標上呼叫,但它同時指定目標屬性和來源屬性。 目標屬性指定為 BindableProperty 物件:Label.RotationProperty
。 來源屬性指定為字串,並指出 Slider 的 Value
屬性。
重要
目標屬性都必須受到可繫結屬性的支援。 因此,目標對象必須是衍生自 BindableObject的類別實例。 如需詳細資訊,請參閱 可系結屬性。
source 屬性會指定為字串。 就內部而言,會使用反映來存取實際的屬性。 不過在這個特定案例中,Value
屬性也受到可繫結屬性支援。
或者,數據系結可以在 XAML 中指定:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingDemos.BasicXamlBindingPage"
Title="Basic XAML Binding">
<StackLayout Padding="10, 0">
<Label Text="TEXT"
FontSize="80"
HorizontalOptions="Center"
VerticalOptions="Center"
BindingContext="{x:Reference Name=slider}"
Rotation="{Binding Path=Value}" />
<Slider x:Name="slider"
Maximum="360"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
如同程式碼,資料繫結是在目標物件上設定,也就是 Label。 兩個 XAML 標記延伸可用來定義資料系結:
- 需要
x:Reference
標記延伸才能參考來源物件,也就是名為slider
的 Slider。 Binding
標記延伸會將 Label 的Rotation
屬性連結至 Slider 的Value
屬性。
如需 XAML 標記延伸的詳細資訊,請參閱 取用 XAML 標記延伸。
注意
source 屬性是使用 Path
標記延伸的 Binding
屬性來指定,其對應於 Path
類別的 Binding
屬性。
XAML 標記延伸,例如 x:Reference
和 Binding
可以定義「內容屬性」屬性,這對於 XAML 標記延伸表示屬性名稱不需要出現。 Name
屬性是 x:Reference
的內容屬性,而 Path
屬性是 Binding
的內容屬性,這表示它們可以從運算式排除:
<Label Text="TEXT"
FontSize="80"
HorizontalOptions="Center"
VerticalOptions="Center"
BindingContext="{x:Reference slider}"
Rotation="{Binding Value}" />
重要
您可以使用編譯的系結來改善系結效能。 如需詳細資訊,請參閱 編譯的系結。
沒有系結內容的系結
BindingContext
屬性是資料繫結的重要元件,但是它不一定必要。 您可以改為在 SetBinding
呼叫或 Binding
標記延伸中指定來源物件:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingDemos.AlternativeCodeBindingPage"
Title="Alternative Code Binding">
<StackLayout Padding="10, 0">
<Label x:Name="label"
Text="TEXT"
FontSize="40"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Slider x:Name="slider"
Minimum="-2"
Maximum="2"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>
在此範例中, Slider 會定義 以控制 Scale
的 Label屬性。 因此, Slider 會針對 -2 到 2 的範圍設定 。
程序代碼後置檔案會使用 SetBinding
方法設定系結,而第二個自變數是 類別的 Binding
建構函式:
public partial class AlternativeCodeBindingPage : ContentPage
{
public AlternativeCodeBindingPage()
{
InitializeComponent();
label.SetBinding(Label.ScaleProperty, new Binding("Value", source: slider));
}
}
Binding
建構函式有 6 個參數,因此會使用具名引數來指定 source
參數。 引數是 slider
物件。
注意
VisualElement 類別也會定義 ScaleX
和 ScaleY
屬性,它們可以在水平和垂直方向以不同的方式調整 VisualElement。
或者,數據系結可以在 XAML 中指定:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingDemos.AlternativeXamlBindingPage"
Title="Alternative XAML Binding">
<StackLayout Padding="10, 0">
<Label Text="TEXT"
FontSize="40"
HorizontalOptions="Center"
VerticalOptions="Center"
Scale="{Binding Source={x:Reference slider},
Path=Value}" />
<Slider x:Name="slider"
Minimum="-2"
Maximum="2"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
在此範例中 Binding
,標記延伸有兩個屬性集, Source
並以 Path
逗號分隔。 Source
屬性設定為內嵌的 x:Reference
標記延伸,這在其他方面具有與設定 BindingContext
相同的語法。
Binding
標記延伸的內容屬性是 Path
,但只有在它是運算式中的第一個屬性時,才能去除標記延伸的 Path=
部分。 若要去除 Path=
部分,您需要交換兩個屬性:
Scale="{Binding Value, Source={x:Reference slider}}" />
雖然 XAML 標記延伸通常以大括弧分隔,它們也可以用物件項目來表示:
<Label Text="TEXT"
FontSize="40"
HorizontalOptions="Center"
VerticalOptions="Center">
<Label.Scale>
<Binding Source="{x:Reference slider}"
Path="Value" />
</Label.Scale>
</Label>
在此範例中 Source
,和 Path
屬性是一般 XAML 屬性。 值出現在引號內,且屬性不以逗號分隔。 x:Reference
標記延伸也可以成為物件項目:
<Label Text="TEXT"
FontSize="40"
HorizontalOptions="Center"
VerticalOptions="Center">
<Label.Scale>
<Binding Path="Value">
<Binding.Source>
<x:Reference Name="slider" />
</Binding.Source>
</Binding>
</Label.Scale>
</Label>
此語法不常見,但有時候涉及複雜物件時會需要。
到目前為止所顯示的範例,會將 BindingContext
屬性和 Binding
的 Source
屬性設定為 x:Reference
標記延伸,以參考頁面上的另一個檢視。 這兩個屬性都屬於類型 Object
,並可以設定為任何物件,物件內包含適合繫結來源的屬性。 您也可以將 BindingContext
或 Source
屬性設定為 x:Static
標記延伸,以參考靜態屬性或字段的值,或 StaticResource
標記延伸來參考儲存在資源字典中的物件,或直接參考物件,這通常是 ViewModel 的實例。
注意
BindingContext
屬性也可以設定為 Binding
物件,以便 Binding
的 Source
和 Path
屬性能定義繫結內容。
系結內容繼承
您可以使用 屬性或 Source
物件的 屬性Binding
來指定來源BindingContext
物件。 如果同時設定,Binding
的 Source
屬性會優先於 BindingContext
。
重要
BindingContext
屬性值會透過可視化樹狀結構繼承。
下列 XAML 範例示範系結內容繼承:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingDemos.BindingContextInheritancePage"
Title="BindingContext Inheritance">
<StackLayout Padding="10">
<StackLayout VerticalOptions="Fill"
BindingContext="{x:Reference slider}">
<Label Text="TEXT"
FontSize="80"
HorizontalOptions="Center"
VerticalOptions="End"
Rotation="{Binding Value}" />
<BoxView Color="#800000FF"
WidthRequest="180"
HeightRequest="40"
HorizontalOptions="Center"
VerticalOptions="Start"
Rotation="{Binding Value}" />
</StackLayout>
<Slider x:Name="slider"
Maximum="360" />
</StackLayout>
</ContentPage>
在此範例中 BindingContext
,的 StackLayout 屬性會設定為 slider
物件。 這個繫結內容同時由 Label 和 BoxView 繼承,這兩者的 Rotation
屬性都設定為 Slider 的 Value
屬性: