BindableLayout
Привязываемые макеты многоплатформенного пользовательского интерфейса приложений .NET (.NET MAUI) позволяют любому классу макета, производным от Layout класса, создавать его содержимое путем привязки к коллекции элементов, с параметром задать внешний вид каждого элемента.DataTemplate
Привязываемые макеты предоставляются классом BindableLayout , который предоставляет следующие присоединенные свойства:
ItemsSource
— указывает коллекцию элементов, отображаемыхIEnumerable
макетом.ItemTemplate
— задает DataTemplate применение к каждому элементу в коллекции элементов, отображаемых макетом.ItemTemplateSelector
— указывает DataTemplateSelector , что будет использоваться для выбора DataTemplate элемента во время выполнения.
Примечание.
Свойство ItemTemplate
имеет приоритет, если заданы оба ItemTemplate
ItemTemplateSelector
свойства.
Кроме того, BindableLayout класс предоставляет следующие привязываемые свойства:
EmptyView
— указываетstring
или представление, которое будет отображаться, еслиItemsSource
свойство равноnull
или когда коллекция, указаннаяItemsSource
свойствомnull
, или пуста. Значение по умолчанию —null
.EmptyViewTemplate
— задает DataTemplate значение, которое будет отображаться, еслиItemsSource
свойство равноnull
или когда коллекция, указаннаяItemsSource
свойством, илиnull
пуста. Значение по умолчанию —null
.
Примечание.
Свойство EmptyViewTemplate
имеет приоритет, если заданы оба EmptyView
EmptyViewTemplate
свойства.
Все эти свойства могут быть присоединены к AbsoluteLayoutклассам , FlexLayout, HorizontalStackLayoutGridи StackLayoutVerticalStackLayout классам, производным Layout от класса.
BindableLayout.ItemsSource
Если свойству присвоено значение коллекции элементов и присоединено к Layoutпроизводному классу, каждый элемент в коллекции добавляется в Layoutпроизводный класс для отображения. Затем производный Layoutкласс обновляет дочерние представления при изменении базовой коллекции.
Привязываемые макеты следует использовать только в том случае, если коллекция элементов для отображения невелика, а прокрутка и выделение не требуются. Хотя прокрутка может быть предоставлена путем упаковки привязываемого макета в a ScrollView, это не рекомендуется, так как привязываемые макеты не имеют виртуализации пользовательского интерфейса. Если требуется прокрутка, необходимо использовать прокручиваемое представление, включающее виртуализацию пользовательского интерфейса, например ListView или CollectionView. Сбой в наблюдении за этой рекомендацией может привести к проблемам с производительностью.
Внимание
Хотя технически можно подключить привязываемый макет к любому классу макета, наследуемому AbsoluteLayout от Layout класса, это не всегда удобно сделать, особенно для классов и Grid классов. Например, рассмотрим сценарий отображения коллекции данных в Grid привязываемом макете, где каждый элемент в коллекции является объектом, содержащим несколько свойств. Каждая строка в Grid коллекции должна отображать объект из коллекции с каждым столбцом в Grid отображении одного из свойств объекта. DataTemplate Так как для привязываемого макета может содержаться только один объект, это необходимо для того, чтобы этот объект был классом макета, содержащим несколько представлений, каждый из которых отображает одно из свойств объекта в определенном Grid столбце. Хотя этот сценарий можно реализовать с привязываемыми макетами, он приводит к Grid родительскому элементу, содержашему дочерний Grid элемент в связанной коллекции, что является очень неэффективным и проблемным использованием макета Grid .
Заполнение привязываемого макета данными
Привязываемый макет заполняется данными, задав его ItemsSource
свойство любой коллекции, реализующей IEnumerable
и присоединяя ее к производном классу Layout:
<Grid BindableLayout.ItemsSource="{Binding Items}" />
Эквивалентный код на C# выглядит так:
IEnumerable<string> items = ...;
Grid 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>
<Image Source="{Binding}"
Aspect="AspectFill"
WidthRequest="44"
HeightRequest="44"
... />
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
Эквивалентный код на C# выглядит так:
DataTemplate imageTemplate = ...;
StackLayout stackLayout = new StackLayout();
BindableLayout.SetItemsSource(stackLayout, viewModel.User.TopFollowers);
BindableLayout.SetItemTemplate(stackLayout, imageTemplate);
В этом примере каждый элемент в TopFollowers
коллекции будет отображаться представлениемImage, определенным в :DataTemplate
Дополнительные сведения о шаблонах данных см. в разделе "Шаблоны данных".
Выбор внешнего вида элемента во время выполнения
Внешний вид каждого элемента в привязываемом макете можно выбрать во время выполнения на основе значения элемента, задав BindableLayout.ItemTemplateSelector
присоединенное свойство следующим DataTemplateSelectorобразом:
<FlexLayout BindableLayout.ItemsSource="{Binding User.FavoriteTech}"
BindableLayout.ItemTemplateSelector="{StaticResource TechItemTemplateSelector}"
... />
Эквивалентный код на C# выглядит так:
DataTemplateSelector dataTemplateSelector = new TechItemTemplateSelector { ... };
FlexLayout flexLayout = new FlexLayout();
BindableLayout.SetItemsSource(flexLayout, viewModel.User.FavoriteTech);
BindableLayout.SetItemTemplateSelector(flexLayout, dataTemplateSelector);
В следующем примере показан TechItemTemplateSelector
класс:
public class TechItemTemplateSelector : DataTemplateSelector
{
public DataTemplate DefaultTemplate { get; set; }
public DataTemplate MAUITemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
return (string)item == ".NET MAUI" ? MAUITemplate : DefaultTemplate;
}
}
Класс TechItemTemplateSelector
определяет DefaultTemplate
и MAUITemplate
DataTemplate свойства, которые задаются различными шаблонами данных. Метод OnSelectTemplate
возвращает MAUITemplate
элемент, который отображает элемент в темно-красном цвете с сердцем рядом с ним, когда элемент равен .NET MAUI. Если элемент не равен .NET MAUI", OnSelectTemplate
метод возвращает DefaultTemplate
объект, который отображает элемент с использованием цвета по умолчанию:Label
Дополнительные сведения о селекторах шаблонов данных см. в разделе "Создание объекта DataTemplateSelector".
Отображение строки при недоступности данных
Свойство EmptyView
может быть задано строкой, которая будет отображаться Label в случае, если ItemsSource
свойство имеет null
значение, или когда коллекция, указанная ItemsSource
свойством null
, или пуста. В следующем коде XAML показан пример этого сценария:
<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}"
BindableLayout.EmptyView="No achievements">
...
</StackLayout>
Результатом является то, что при сборе null
привязанных к данным строке EmptyView
отображается значение свойства:
Отображение представлений при недоступности данных
Свойство EmptyView
может быть задано в представлении, которое будет отображаться, если ItemsSource
свойство равно null
или когда коллекция, указанная 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
свойство равно null
или когда коллекция, указанная ItemsSource
свойством, или 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 определяет два ContentView объекта на уровне ResourceDictionaryстраницы с Switch объектом, определяющим, какой ContentView объект будет задан в качестве EmptyView
значения свойства. Switch При переключение OnEmptyViewSwitchToggled
обработчик событий выполняет ToggleEmptyView
метод:
void ToggleEmptyView(bool isToggled)
{
object view = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
BindableLayout.SetEmptyView(stackLayout, view);
}
Метод ToggleEmptyView
задает EmptyView
свойство StackLayout объекта одному из двух ContentView объектов, хранящихся в объекте ResourceDictionary, на основе значения Switch.IsToggled
свойства. Затем, когда коллекция null
привязанных к данным данных, ContentView объект, заданный в качестве EmptyView
свойства, отображается.