相對系結可讓您設定系結來源相對於系結目標的位置。 它們會使用 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 控件範本。


