中的可系結版面配置 Xamarin.Forms
可系結的配置可讓衍生自 Layout<T>
類別的任何版面配置類別,藉由系結至專案集合來產生其內容,以及使用 設定每個專案 DataTemplate
外觀的選項。 可系結的配置是由 BindableLayout
類別提供,其會公開下列附加屬性:
ItemsSource
– 指定要由版面設定顯示的項目集合IEnumerable
。ItemTemplate
– 指定要DataTemplate
套用至版面設定所顯示項目集合中每個項目的 。ItemTemplateSelector
– 指定DataTemplateSelector
在執行時間為項目選擇DataTemplate
的 。
注意
設定 ItemTemplate
和 ItemTemplateSelector
屬性時ItemTemplate
,屬性會優先使用。
此外,類別 BindableLayout
會公開下列可系結屬性:
EmptyView
– 指定string
當 屬性為 時,或 當 屬性null
所ItemsSource
指定的集合為null
或空白時,將會顯示的ItemsSource
或檢視。 預設值是null
。EmptyViewTemplate
– 指定DataTemplate
當 屬性為 時,ItemsSource
或 當 屬性指定的集合為null
null
或空白時,將顯示的ItemsSource
。 預設值是null
。
注意
設定 EmptyViewTemplate
和 EmptyViewTemplate
屬性時EmptyView
,屬性會優先使用。
所有這些屬性都可以附加至 AbsoluteLayout
、FlexLayout
、、 RelativeLayout
Grid
和 StackLayout
類別,這些屬性全都衍生自 Layout<T>
類別。
類別 Layout<T>
會 Children
公開集合,其中會加入版面配置的子專案。 BindableLayout.ItemsSource
當屬性設定為專案集合並附加至Layout<T>
衍生類別時,集合中的每個項目都會新增至集合,Layout<T>.Children
以供版面配置顯示。 Layout<T>
衍生類別會在基礎集合變更時更新其子檢視。 如需配置週期的詳細資訊 Xamarin.Forms ,請參閱 建立自定義版面配置。
只有當要顯示的專案集合很小,而且不需要捲動和選取時,才應該使用可繫結的配置。 雖然捲動可以藉由在 中 ScrollView
包裝可繫結的版面配置來提供,但不建議這麼做,因為可系結的配置缺少UI虛擬化。 需要捲動時,應該使用包含UI虛擬化的可捲動檢視,例如 ListView
或 CollectionView
。 如果無法觀察這項建議,可能會導致效能問題。
重要
雖然從技術上講,可以將可系結的配置附加至衍生自 Layout<T>
類別的任何版面配置類別, AbsoluteLayout
但對 、 Grid
和 RelativeLayout
類別而言,不一定可行。 例如,假設想要使用可系結配置在 中 Grid
顯示數據的集合,其中集合中的每個專案都是包含多個屬性的物件。 中的每個 Grid
數據列都應該顯示集合中的物件,其中每一個數據行都會 Grid
顯示其中一個對象的屬性。 DataTemplate
因為可系結配置的 只能包含單一物件,所以該對象必須是包含多個檢視的版面配置類別,每個檢視都會在特定數據行中顯示其中一個Grid
對象的屬性。 雖然此案例可以透過可系結的配置來實現,但會導致 Grid
父系包含系結集合中每個專案的子 Grid
系,這是配置非常沒有效率且有問題的使用 Grid
方式。
使用數據填入可系結的版面配置
可系結的配置會填入數據,方法是將其 ItemsSource
屬性設定為任何實作 的集合 IEnumerable
,並將它附加至 Layout<T>
衍生類別:
<Grid BindableLayout.ItemsSource="{Binding Items}" />
對等的 C# 程式碼為:
IEnumerable<string> items = ...;
var grid = new Grid();
BindableLayout.SetItemsSource(grid, items);
BindableLayout.ItemsSource
在版面配置上設定附加屬性,但BindableLayout.ItemTemplate
未設定附加屬性時,集合中的每個IEnumerable
項目都會由 Label
類別所BindableLayout
建立的 顯示。
定義項目外觀
您可以在可繫結設定中定義每個項目的外觀,方法是將 BindableLayout.ItemTemplate
附加屬性設定為 DataTemplate
:
<StackLayout BindableLayout.ItemsSource="{Binding User.TopFollowers}"
Orientation="Horizontal"
...>
<BindableLayout.ItemTemplate>
<DataTemplate>
<controls:CircleImage Source="{Binding}"
Aspect="AspectFill"
WidthRequest="44"
HeightRequest="44"
... />
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
對等的 C# 程式碼為:
DataTemplate circleImageTemplate = ...;
var stackLayout = new StackLayout();
BindableLayout.SetItemsSource(stackLayout, viewModel.User.TopFollowers);
BindableLayout.SetItemTemplate(stackLayout, circleImageTemplate);
在此範例中,集合中的每個 TopFollowers
項目都會由 CircleImage
中 DataTemplate
定義的檢視顯示:
如需數據範本的詳細資訊,請參閱 Xamarin.Forms 數據範本。
選擇運行時間的項目外觀
您可以藉由附加屬性設定 BindableLayout.ItemTemplateSelector
為 DataTemplateSelector
,在執行時間根據專案值,選擇可繫結配置中每個項目的外觀:
<FlexLayout BindableLayout.ItemsSource="{Binding User.FavoriteTech}"
BindableLayout.ItemTemplateSelector="{StaticResource TechItemTemplateSelector}"
... />
對等的 C# 程式碼為:
DataTemplateSelector dataTemplateSelector = new TechItemTemplateSelector { ... };
var flexLayout = new FlexLayout();
BindableLayout.SetItemsSource(flexLayout, viewModel.User.FavoriteTech);
BindableLayout.SetItemTemplateSelector(flexLayout, dataTemplateSelector);
DataTemplateSelector
範例應用程式中所使用的 ,如下列範例所示:
public class TechItemTemplateSelector : DataTemplateSelector
{
public DataTemplate DefaultTemplate { get; set; }
public DataTemplate XamarinFormsTemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
return (string)item == "Xamarin.Forms" ? XamarinFormsTemplate : DefaultTemplate;
}
}
類別 TechItemTemplateSelector
會 DefaultTemplate
定義 和 XamarinFormsTemplate
DataTemplate
屬性,這些屬性會設定為不同的數據範本。 方法 OnSelectTemplate
會 XamarinFormsTemplate
傳回 ,當專案等於 “Xamarin.Forms” 時,會以深紅色顯示專案,旁邊有心形。 當專案不等於 「Xamarin.Forms」時, OnSelectTemplate
方法會傳回 DefaultTemplate
,它會使用的預設色彩 Label
來顯示專案:
如需數據範本選取器的詳細資訊,請參閱 建立 Xamarin.Forms DataTemplateSelector。
當數據無法使用時顯示字串
屬性EmptyView
可以設定為字串,當 屬性為 null
時ItemsSource
,或屬性所ItemsSource
指定的集合為 null
或空白時,就會顯示Label
該字串。 下列 XAML 顯示此案例的範例:
<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}"
BindableLayout.EmptyView="No achievements">
...
</StackLayout>
結果是,當數據系結集合為 null
時,會顯示為 屬性值的 EmptyView
字串:
當數據無法使用時顯示檢視
屬性EmptyView
可以設定為檢視,當 屬性為 null
時ItemsSource
,或屬性指定的ItemsSource
集合為 null
或空白時,就會顯示該檢視。 這可以是單一檢視或包含多個子檢視的檢視。 下列 XAML 範例顯示 EmptyView
屬性設定為包含多個子檢視的檢視:
<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}">
<BindableLayout.EmptyView>
<StackLayout>
<Label Text="None."
FontAttributes="Italic"
FontSize="{StaticResource smallTextSize}" />
<Label Text="Try harder and return later?"
FontAttributes="Italic"
FontSize="{StaticResource smallTextSize}" />
</StackLayout>
</BindableLayout.EmptyView>
...
</StackLayout>
結果是當數據系結集合為 null
時, StackLayout
會顯示 及其子檢視。
同樣地,EmptyViewTemplate
可以將 設定為 DataTemplate
,當 屬性為 時ItemsSource
,或 當 屬性指定的ItemsSource
集合為 null
null
或空白時,就會顯示該屬性。 DataTemplate
可以包含單一檢視,或包含多個子檢視的檢視。 此外, BindingContext
的 EmptyViewTemplate
會繼承自 BindingContext
的 BindableLayout
。 下列 XAML 範例顯示 EmptyViewTemplate
屬性設定為 DataTemplate
包含單一檢視的 :
<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}">
<BindableLayout.EmptyViewTemplate>
<DataTemplate>
<Label Text="{Binding Source={x:Reference usernameLabel}, Path=Text, StringFormat='{0} has no achievements.'}" />
</DataTemplate>
</BindableLayout.EmptyViewTemplate>
...
</StackLayout>
結果是當資料系結集合為 null
時, Label
會顯示 中的 DataTemplate
:
注意
EmptyViewTemplate
無法透過 DataTemplateSelector
設定屬性。
在運行時間選擇 EmptyView
當數據無法使用時,會顯示為 EmptyView
的檢視,可以定義為 ContentView
中的 ResourceDictionary
物件。 EmptyView
屬性接著可以在執行時間根據某些商業規則,設定為特定的 ContentView
。 下列 XAML 顯示此案例的範例:
<ContentPage ...>
<ContentPage.Resources>
...
<ContentView x:Key="BasicEmptyView">
<StackLayout>
<Label Text="No achievements."
FontSize="14" />
</StackLayout>
</ContentView>
<ContentView x:Key="AdvancedEmptyView">
<StackLayout>
<Label Text="None."
FontAttributes="Italic"
FontSize="14" />
<Label Text="Try harder and return later?"
FontAttributes="Italic"
FontSize="14" />
</StackLayout>
</ContentView>
</ContentPage.Resources>
<StackLayout>
...
<Switch Toggled="OnEmptyViewSwitchToggled" />
<StackLayout x:Name="stackLayout"
BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}">
...
</StackLayout>
</StackLayout>
</ContentPage>
XAML 會在頁面層級ResourceDictionary
中定義兩個 ContentView
物件,而 Switch
物件會控制哪些ContentView
物件將設定為 EmptyView
屬性值。 Switch
切換 時,OnEmptyViewSwitchToggled
事件處理程式會ToggleEmptyView
執行 方法:
void ToggleEmptyView(bool isToggled)
{
object view = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
BindableLayout.SetEmptyView(stackLayout, view);
}
方法會ToggleEmptyView
根據 屬性的值Switch.IsToggled
,將 EmptyView
對象的 屬性stackLayout
設定為儲存在 中ResourceDictionary
之兩ContentView
個 物件的其中一個。 然後,當數據系結集合為 null
時, ContentView
會顯示當做 EmptyView
屬性設定的物件: