의 바인딩 가능한 레이아웃 Xamarin.Forms
바인딩 가능한 레이아웃을 사용하면 클래스에서 Layout<T>
파생된 모든 레이아웃 클래스가 항목 컬렉션에 바인딩하여 콘텐츠를 생성할 수 있으며, 각 항목의 모양을 설정할 수 있습니다 DataTemplate
. 바인딩 가능한 레이아웃은 클래스에서 BindableLayout
제공하며, 이 레이아웃은 다음과 같은 연결된 속성을 노출합니다.
ItemsSource
– 레이아웃에서 표시할 항목의IEnumerable
컬렉션을 지정합니다.ItemTemplate
– 레이아웃에DataTemplate
표시되는 항목 컬렉션의 각 항목에 적용할 항목을 지정합니다.ItemTemplateSelector
– 런타임에 항목을 선택하는DataTemplate
데 사용할 항목을 지정DataTemplateSelector
합니다.
참고 항목
속성과 ItemTemplate
ItemTemplateSelector
속성이 모두 설정되면 속성이 ItemTemplate
우선합니다.
또한 클래스는 BindableLayout
다음 바인딩 가능한 속성을 노출합니다.
EmptyView
– 속성이string
있을 때ItemsSource
또는 속성에서 지정한 컬렉션이null
비어 있거나 비어 있을 때 표시될 뷰를ItemsSource
null
지정합니다. 기본값은null
입니다.EmptyViewTemplate
– 속성이 있을 때ItemsSource
또는 속성에 지정된ItemsSource
컬렉션이null
비어 있거나 비어 있을 때 표시할 값을null
지정DataTemplate
합니다. 기본값은null
입니다.
참고 항목
속성과 EmptyViewTemplate
EmptyViewTemplate
속성이 모두 설정되면 속성이 EmptyView
우선합니다.
이러한 모든 속성은 클래스에서 파생되는 , FlexLayout
, RelativeLayout
Grid
및 StackLayout
클래스에 Layout<T>
연결할 AbsoluteLayout
수 있습니다.
클래스는 Layout<T>
레이아웃의 Children
자식 요소가 추가되는 컬렉션을 노출합니다. BindableLayout.ItemsSource
속성이 항목 컬렉션으로 설정되고 파생 클래스에 Layout<T>
연결된 경우 컬렉션의 각 항목이 레이아웃에 의해 표시되도록 Layout<T>.Children
컬렉션에 추가됩니다. 그러면 -derived 클래스는 Layout<T>
기본 컬렉션이 변경될 때 해당 자식 뷰를 업데이트합니다. 레이아웃 주기에 Xamarin.Forms 대한 자세한 내용은 사용자 지정 레이아웃 만들기를 참조하세요.
바인딩 가능한 레이아웃은 표시할 항목 컬렉션이 작고 스크롤 및 선택이 필요하지 않은 경우에만 사용해야 합니다. 바인딩 가능한 레이아웃을 래핑하여 스크롤을 제공할 수 있지만 바인딩 가능한 레이아웃 ScrollView
에 UI 가상화가 없기 때문에 권장되지 않습니다. 스크롤이 필요한 경우 UI 가상화(예: ListView
또는 CollectionView
)를 포함하는 스크롤 가능한 뷰를 사용해야 합니다. 이 권장 사항을 준수하지 않으면 성능 문제가 발생할 수 있습니다.
Important
기술적으로는 클래스에서 Layout<T>
파생된 모든 레이아웃 클래스에 바인딩 가능한 레이아웃을 연결할 수 있지만, 특히 , Grid
및 RelativeLayout
클래스에 대해 AbsoluteLayout
바인딩 가능한 레이아웃을 연결하는 것이 항상 실용적인 것은 아닙니다. 예를 들어 바인딩 가능한 레이아웃을 사용하여 데이터 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 데이터 템플릿을 참조하세요.
런타임에 항목 모양 선택
연결된 속성을 DataTemplateSelector
다음으로 설정 BindableLayout.ItemTemplateSelector
하여 런타임에 바인딩 가능한 레이아웃의 각 항목 모양을 항목 값에 따라 선택할 수 있습니다.
<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"와 같을 때 옆에 하트가 있는 진한 빨간색으로 표시된 항목을 반환합니다. 항목이 ""이 아닌 경우 메서드는 OnSelectTemplate
기본 색Label
을 사용하여 항목을 표시하는 다음Xamarin.Forms을 반환DefaultTemplate
합니다.
데이터 템플릿 선택기에 대한 자세한 내용은 DataTemplateSelector 만들기를 Xamarin.Forms 참조하세요.
데이터를 사용할 수 없는 경우 문자열 표시
속성을 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
있을 때 ItemsSource
또는 속성에서 DataTemplate
지정 ItemsSource
한 컬렉션이 null
비어 있거나 비어 있을 때 표시되는 로 설정할 수 있습니다null
. 단일 DataTemplate
보기 또는 여러 자식 뷰가 포함된 뷰를 포함할 수 있습니다. 또한 의 BindingContext
상속 됩니다 BindingContext
BindableLayout
.EmptyViewTemplate
다음 XAML 예제에서는 단일 보기를 포함하는 속성 집합 DataTemplate
을 보여 EmptyViewTemplate
줍니다.
<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
될 뷰는 에 개체ResourceDictionary
로 ContentView
정의할 수 있습니다. 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은 속성 값으로 설정될 개체를 제어하는 개체를 Switch
사용하여 ContentView
페이지 수준에서 ResourceDictionary
두 ContentView
개체를 EmptyView
정의합니다. Switch
토글 OnEmptyViewSwitchToggled
되면 이벤트 처리기가 메서드를 ToggleEmptyView
실행합니다.
void ToggleEmptyView(bool isToggled)
{
object view = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
BindableLayout.SetEmptyView(stackLayout, view);
}
메서드는 ToggleEmptyView
속성 값에 Switch.IsToggled
따라 개체의 stackLayout
속성을 저장된 ResourceDictionary
두 ContentView
개체 중 하나로 설정합니다EmptyView
. 그런 다음 데이터 바인딩된 컬렉션이 있으면 null
ContentView
속성으로 EmptyView
설정된 개체가 표시됩니다.