Udostępnij za pośrednictwem


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 DataTemplatewartość . Istnieje wiele technik, których można użyć do wykonania tego zadania:

Niezależnie od używanej techniki wynik polega na tym, że wygląd każdej komórki w ListView obiekcie jest zdefiniowany przez DataTemplateelement , jak pokazano na poniższych zrzutach ekranu:

ListView z elementem DataTemplate

Tworzenie wbudowanego elementu DataTemplate

Właściwość ListView.ItemTemplate można ustawić na wbudowany DataTemplateelement . 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 ViewCellukł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 ResourceDictionarykodu 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.