Tworzenie elementu Xamarin.Forms DataTemplate
Szablony danych można tworzyć w tekście, w elemedycie ResourceDictionary lub na podstawie niestandardowego typu lub odpowiedniego Xamarin.Forms typu komórki. W tym artykule omówiono każdą technikę.
Typowy scenariusz użycia obiektu DataTemplate
to wyświetlanie danych z kolekcji obiektów w obiekcie ListView
. Wygląd danych dla każdej komórki w ListView
obiekcie może być zarządzany przez ustawienie ListView.ItemTemplate
właściwości na DataTemplate
wartość . Istnieje wiele technik, których można użyć do wykonania tego zadania:
- Tworzenie wbudowanego elementu DataTemplate.
- Tworzenie elementu DataTemplate z typem.
- Tworzenie elementu DataTemplate jako zasobu.
Niezależnie od używanej techniki wynik polega na tym, że wygląd każdej komórki w ListView
obiekcie jest zdefiniowany przez DataTemplate
element , jak pokazano na poniższych zrzutach ekranu:
Tworzenie wbudowanego elementu DataTemplate
Właściwość ListView.ItemTemplate
można ustawić na wbudowany DataTemplate
element . Szablon wbudowany, który jest umieszczony jako bezpośredni element podrzędny odpowiedniej właściwości kontrolki, powinien być używany, jeśli nie ma potrzeby ponownego używania szablonu danych w innym miejscu. Elementy określone w definicji DataTemplate
wyglądu każdej komórki, jak pokazano w poniższym przykładzie kodu XAML:
<ListView Margin="0,20,0,0">
<ListView.ItemsSource>
<x:Array Type="{x:Type local:Person}">
<local:Person Name="Steve" Age="21" Location="USA" />
<local:Person Name="John" Age="37" Location="USA" />
<local:Person Name="Tom" Age="42" Location="UK" />
<local:Person Name="Lucas" Age="29" Location="Germany" />
<local:Person Name="Tariq" Age="39" Location="UK" />
<local:Person Name="Jane" Age="30" Location="USA" />
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
...
<Label Text="{Binding Name}" FontAttributes="Bold" />
<Label Grid.Column="1" Text="{Binding Age}" />
<Label Grid.Column="2" Text="{Binding Location}" HorizontalTextAlignment="End" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Element podrzędny śródliniowej DataTemplate
musi mieć wartość lub pochodzić z typu Cell
. W tym przykładzie użyto obiektu ViewCell
, który pochodzi z klasy Cell
. Układ wewnątrz elementu ViewCell
jest zarządzany tutaj przez element Grid
. Zawiera Grid
trzy Label
wystąpienia, które wiążą ich Text
właściwości z odpowiednimi właściwościami każdego Person
obiektu w kolekcji.
Równoważny kod języka C# jest pokazany w poniższym przykładzie kodu:
public class WithDataTemplatePageCS : ContentPage
{
public WithDataTemplatePageCS()
{
...
var people = new List<Person>
{
new Person { Name = "Steve", Age = 21, Location = "USA" },
...
};
var personDataTemplate = new DataTemplate(() =>
{
var grid = new Grid();
...
var nameLabel = new Label { FontAttributes = FontAttributes.Bold };
var ageLabel = new Label();
var locationLabel = new Label { HorizontalTextAlignment = TextAlignment.End };
nameLabel.SetBinding(Label.TextProperty, "Name");
ageLabel.SetBinding(Label.TextProperty, "Age");
locationLabel.SetBinding(Label.TextProperty, "Location");
grid.Children.Add(nameLabel);
grid.Children.Add(ageLabel, 1, 0);
grid.Children.Add(locationLabel, 2, 0);
return new ViewCell { View = grid };
});
Content = new StackLayout
{
Margin = new Thickness(20),
Children = {
...
new ListView { ItemsSource = people, ItemTemplate = personDataTemplate, Margin = new Thickness(0, 20, 0, 0) }
}
};
}
}
W języku C#wiersz DataTemplate
jest tworzony przy użyciu przeciążenia konstruktora, który określa Func
argument.
Tworzenie elementu DataTemplate z typem
Właściwość ListView.ItemTemplate
można również ustawić na utworzoną DataTemplate
na podstawie typu komórki. Zaletą tego podejścia jest to, że wygląd zdefiniowany przez typ komórki może być ponownie używany przez wiele szablonów danych w całej aplikacji. Poniższy kod XAML przedstawia przykład tego podejścia:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataTemplates"
...>
<StackLayout Margin="20">
...
<ListView Margin="0,20,0,0">
<ListView.ItemsSource>
<x:Array Type="{x:Type local:Person}">
<local:Person Name="Steve" Age="21" Location="USA" />
...
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<local:PersonCell />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
ListView.ItemTemplate
W tym miejscu właściwość jest ustawiona na utworzoną DataTemplate
na podstawie typu niestandardowego, który definiuje wygląd komórki. Typ niestandardowy musi pochodzić z typu ViewCell
, jak pokazano w poniższym przykładzie kodu:
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataTemplates.PersonCell">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.3*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}" FontAttributes="Bold" />
<Label Grid.Column="1" Text="{Binding Age}" />
<Label Grid.Column="2" Text="{Binding Location}" HorizontalTextAlignment="End" />
</Grid>
</ViewCell>
W programie ViewCell
układ jest zarządzany tutaj przez element Grid
. Zawiera Grid
trzy Label
wystąpienia, które wiążą ich Text
właściwości z odpowiednimi właściwościami każdego Person
obiektu w kolekcji.
Równoważny kod języka C# jest pokazany w poniższym przykładzie:
public class WithDataTemplatePageFromTypeCS : ContentPage
{
public WithDataTemplatePageFromTypeCS()
{
...
var people = new List<Person>
{
new Person { Name = "Steve", Age = 21, Location = "USA" },
...
};
Content = new StackLayout
{
Margin = new Thickness(20),
Children = {
...
new ListView { ItemTemplate = new DataTemplate(typeof(PersonCellCS)), ItemsSource = people, Margin = new Thickness(0, 20, 0, 0) }
}
};
}
}
W języku C# DataTemplate
obiekt jest tworzony przy użyciu przeciążenia konstruktora, który określa typ komórki jako argument. Typ komórki musi pochodzić z typu ViewCell
, jak pokazano w poniższym przykładzie kodu:
public class PersonCellCS : ViewCell
{
public PersonCellCS()
{
var grid = new Grid();
...
var nameLabel = new Label { FontAttributes = FontAttributes.Bold };
var ageLabel = new Label();
var locationLabel = new Label { HorizontalTextAlignment = TextAlignment.End };
nameLabel.SetBinding(Label.TextProperty, "Name");
ageLabel.SetBinding(Label.TextProperty, "Age");
locationLabel.SetBinding(Label.TextProperty, "Location");
grid.Children.Add(nameLabel);
grid.Children.Add(ageLabel, 1, 0);
grid.Children.Add(locationLabel, 2, 0);
View = grid;
}
}
Uwaga
Należy pamiętać, że Xamarin.Forms zawiera również typy komórek, których można użyć do wyświetlania prostych danych w ListView
komórkach. Aby uzyskać więcej informacji, zobacz Wygląd komórki.
Tworzenie elementu DataTemplate jako zasobu
Szablony danych można również tworzyć jako obiekty wielokrotnego użytku w obiekcie ResourceDictionary
. Jest to osiągane przez nadanie każdej deklaracji unikatowego x:Key
atrybutu, który zapewnia mu klucz opisowy w pliku , jak pokazano w poniższym przykładzie ResourceDictionary
kodu XAML:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
...>
<ContentPage.Resources>
<ResourceDictionary>
<DataTemplate x:Key="personTemplate">
<ViewCell>
<Grid>
...
</Grid>
</ViewCell>
</DataTemplate>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout Margin="20">
...
<ListView ItemTemplate="{StaticResource personTemplate}" Margin="0,20,0,0">
<ListView.ItemsSource>
<x:Array Type="{x:Type local:Person}">
<local:Person Name="Steve" Age="21" Location="USA" />
...
</x:Array>
</ListView.ItemsSource>
</ListView>
</StackLayout>
</ContentPage>
Właściwość DataTemplate
jest przypisywana do ListView.ItemTemplate
właściwości przy użyciu StaticResource
rozszerzenia znaczników. Należy pamiętać, że chociaż element DataTemplate
jest zdefiniowany na stronie ResourceDictionary
, można go również zdefiniować na poziomie kontroli lub aplikacji.
Poniższy przykład kodu przedstawia równoważną stronę w języku C#:
public class WithDataTemplatePageCS : ContentPage
{
public WithDataTemplatePageCS ()
{
...
var personDataTemplate = new DataTemplate (() => {
var grid = new Grid ();
...
return new ViewCell { View = grid };
});
Resources = new ResourceDictionary ();
Resources.Add ("personTemplate", personDataTemplate);
Content = new StackLayout {
Margin = new Thickness(20),
Children = {
...
new ListView { ItemTemplate = (DataTemplate)Resources ["personTemplate"], ItemsSource = people };
}
};
}
}
Element DataTemplate
jest dodawany do ResourceDictionary
metody using Add
, która określa Key
ciąg używany do odwołowania DataTemplate
się do elementu podczas pobierania.
Podsumowanie
W tym artykule wyjaśniono, jak tworzyć szablony danych w tekście na podstawie typu niestandardowego lub w elemecie ResourceDictionary
. Szablon wbudowany powinien być używany, jeśli nie ma potrzeby ponownego używania szablonu danych w innym miejscu. Alternatywnie szablon danych można użyć ponownie, definiując go jako typ niestandardowy lub jako zasób na poziomie kontroli, na poziomie strony lub na poziomie aplikacji.