Xamarin.Forms 相對系結
相對系結可讓您設定系結來源相對於系結目標的位置。 它們會使用 RelativeSource
標記延伸來建立,並設定為 Source
系結表達式的 屬性。
類別 RelativeSource
支援 RelativeSourceExtension
標記延伸,其定義下列屬性:
Mode
型RelativeBindingSourceMode
別為 的 ,描述系結來源相對於系結目標位置的位置。AncestorLevel
型int
別為 的選擇性上階層級,當 屬性為FindAncestor
時,要尋找的Mode
選擇性上階層級。AncestorLevel
的n
會n-1
略過的AncestorType
實例。AncestorType
,屬於 類型Type
,當 屬性為FindAncestor
時Mode
,要尋找的上階類型。
注意
XAML 剖析器允許將 RelativeSourceExtension
類別縮寫為 RelativeSource
。
屬性 Mode
應設定為其中 RelativeBindingSourceMode
一個列舉成員:
TemplatedParent
表示套用綁定專案所在範本所在的專案。 如需詳細資訊,請參閱 系結至樣板化父系。Self
表示正在設定系結的專案,可讓您將該專案的一個屬性系結至相同專案上的另一個屬性。 如需詳細資訊,請參閱 系結至自我。FindAncestor
表示綁定項目可視化樹狀結構中的上階。 此模式應該用來系結至 屬性所表示的AncestorType
上階控件。 如需詳細資訊,請參閱 系結至上階。FindAncestorBindingContext
表示BindingContext
繫結項目視覺化樹狀結構中上階的 。 這個模式應該用來繫結至BindingContext
屬性所表示祖系的AncestorType
。 如需詳細資訊,請參閱 系結至上階。
屬性 Mode
是類別的內容 RelativeSourceExtension
屬性。 因此,對於以大括弧表示的 XAML 標記表示式,您可以排除 Mode=
表達式的一部分。
如需標記延伸的詳細資訊 Xamarin.Forms ,請參閱 XAML 標記延伸。
系結至自我
使用相對系結模式會將 Self
元素的屬性系結至相同元素上的另一個屬性:
<BoxView Color="Red"
WidthRequest="200"
HeightRequest="{Binding Source={RelativeSource Self}, Path=WidthRequest}"
HorizontalOptions="Center" />
在此範例中,會將 BoxView
其 WidthRequest
屬性設定為固定大小,而 HeightRequest
屬性會系結至 WidthRequest
屬性。 因此,這兩個屬性都相等,因此繪製正方形:
重要
將專案的屬性系結至相同專案上的另一個屬性時,屬性必須是相同的類型。 或者,您可以在繫結上指定轉換器來轉換值。
此系結模式的常見用法是將 對象的 BindingContext
設定為本身的屬性。 下列程式碼將示範這項作業:
<ContentPage ...
BindingContext="{Binding Source={RelativeSource Self}, Path=DefaultViewModel}">
<StackLayout>
<ListView ItemsSource="{Binding Employees}">
...
</ListView>
</StackLayout>
</ContentPage>
在此範例中, BindingContext
頁面的 設定為 DefaultViewModel
本身的 屬性。 此屬性定義於頁面的程式代碼後置檔案中,並提供 viewmodel 實例。 系 ListView
結至 Employees
viewmodel 的 屬性。
系結至上階
FindAncestor
和 FindAncestorBindingContext
相對系結模式可用來系結至可視化樹狀結構中特定類型的父元素。 模式 FindAncestor
是用來系結至衍生自 型別的 Element
父元素。 模式 FindAncestorBindingContext
是用來繫結至 BindingContext
父元素的 。
警告
AncestorType
使用 FindAncestor
與 FindAncestorBindingContext
相對系結模式時,屬性必須設定為 Type
,否則XamlParseException
會擲回 。
Mode
如果未明確設定 屬性,將 AncestorType
屬性設定為衍生自 Element
的類型,將會隱含地將 Mode
屬性設定為 FindAncestor
。 同樣地,將 AncestorType
屬性設定為不是衍生自 Element
的類型,將會隱含地將 Mode
屬性設定為 FindAncestorBindingContext
。
注意
當任何上階變更時BindingContext
,將會重新套用使用FindAncestorBindingContext
模式的相對系結。
下列 XAML 顯示將隱含地將 屬性設定為 FindAncestorBindingContext
的範例Mode
:
<ContentPage ...
BindingContext="{Binding Source={RelativeSource Self}, Path=DefaultViewModel}">
<StackLayout>
<ListView ItemsSource="{Binding Employees}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Fullname}"
VerticalOptions="Center" />
<Button Text="Delete"
Command="{Binding Source={RelativeSource AncestorType={x:Type local:PeopleViewModel}}, Path=DeleteEmployeeCommand}"
CommandParameter="{Binding}"
HorizontalOptions="EndAndExpand" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
在此範例中, BindingContext
頁面的 設定為 DefaultViewModel
本身的 屬性。 此屬性定義於頁面的程式代碼後置檔案中,並提供 viewmodel 實例。 系 ListView
結至 Employees
viewmodel 的 屬性。 DataTemplate
,定義 中ListView
每個項目的外觀,包含 Button
。 按鈕的 Command
屬性會系結至 DeleteEmployeeCommand
其父系 ViewModel 中的 。 點選 Button
刪除員工:
此外,在可視化樹狀結構中可能有多個上階的上階的情況下,選擇性 AncestorLevel
屬性有助於釐清上階查閱:
<Label Text="{Binding Source={RelativeSource AncestorType={x:Type Entry}, AncestorLevel=2}, Path=Text}" />
在此範例中 Label.Text
,屬性會從系結的目標項目開始,系結至 Text
上路徑上遇到的第二個 Entry
屬性。
注意
屬性 AncestorLevel
應設定為 1,以尋找最接近系結目標元素的上階。
系結至樣板化父系
相對系 TemplatedParent
結模式可用來從控件範本內系結至套用範本的運行時間物件實例(稱為樣板化父系)。 只有在相對系結是在控件範本內,而且類似於設定 TemplateBinding
時,才適用這個模式。
下列 XAML 顯示相對系 TemplatedParent
結模式的範例:
<ContentPage ...>
<ContentPage.Resources>
<ControlTemplate x:Key="CardViewControlTemplate">
<Frame BindingContext="{Binding Source={RelativeSource TemplatedParent}}"
BackgroundColor="{Binding CardColor}"
BorderColor="{Binding BorderColor}"
...>
<Grid>
...
<Label Text="{Binding CardTitle}"
... />
<BoxView BackgroundColor="{Binding BorderColor}"
... />
<Label Text="{Binding CardDescription}"
... />
</Grid>
</Frame>
</ControlTemplate>
</ContentPage.Resources>
<StackLayout>
<controls:CardView BorderColor="DarkGray"
CardTitle="John Doe"
CardDescription="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla elit dolor, convallis non interdum."
IconBackgroundColor="SlateGray"
IconImageSource="user.png"
ControlTemplate="{StaticResource CardViewControlTemplate}" />
<controls:CardView BorderColor="DarkGray"
CardTitle="Jane Doe"
CardDescription="Phasellus eu convallis mi. In tempus augue eu dignissim fermentum. Morbi ut lacus vitae eros lacinia."
IconBackgroundColor="SlateGray"
IconImageSource="user.png"
ControlTemplate="{StaticResource CardViewControlTemplate}" />
<controls:CardView BorderColor="DarkGray"
CardTitle="Xamarin Monkey"
CardDescription="Aliquam sagittis, odio lacinia fermentum dictum, mi erat scelerisque erat, quis aliquet arcu."
IconBackgroundColor="SlateGray"
IconImageSource="user.png"
ControlTemplate="{StaticResource CardViewControlTemplate}" />
</StackLayout>
</ContentPage>
在此範例中, Frame
是的 ControlTemplate
根元素 ,其 BindingContext
已設定為套用範本的運行時間對象實例。 因此, Frame
及其子系會針對每個 CardView
物件的屬性解析其系結表達式:
如需控件範本的詳細資訊,請參閱 Xamarin.Forms 控件範本。