Xamarin.Forms DataTemplate 만들기

Download Sample 샘플 다운로드

데이터 템플릿은 ResourceDictionary에서 인라인으로 만들거나 사용자 지정 형식 또는 적절한 Xamarin.Forms 셀 형식으로 만들 수 있습니다. 이 문서에서는 각 기법을 살펴봅니다.

DataTemplate에 대한 일반적인 시나리오는 ListView에서 개체 컬렉션의 데이터를 표시하는 것입니다. ListView에서 각 셀에 대한 데이터 모양은 ListView.ItemTemplate 속성을 DataTemplate으로 설정하여 관리할 수 있습니다. 이 작업을 수행하는 데 사용할 수 있는 여러 기법이 있습니다.

다음 스크린샷에 표시된 것처럼 사용되는 기법에 관계 없이, ListView에서 각 셀의 모양은 DataTemplate으로 정의됩니다.

ListView with a DataTemplate

인라인 DataTemplate 만들기

ListView.ItemTemplate 속성은 인라인 DataTemplate으로 설정할 수 있습니다. 해당 컨트롤 속성의 직계 자식으로 배치되는 인라인 템플릿은 다른 곳에서 데이터 템플릿을 재사용할 필요가 없는 경우 사용해야 합니다. DataTemplate에 지정된 요소는 다음 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>

인라인 DataTemplate의 자식은 Cell 형식이거나 파생된 것이어야 합니다. 이 예제에서는 Cell에서 파생되는 ViewCell을 사용합니다. ViewCell 내의 레이아웃은 여기서 Grid로 관리됩니다. GridText 속성을 컬렉션에 있는 각 Person 개체의 적절한 속성으로 바인딩하는 세 개의 Label 인스턴스를 포함합니다.

동등한 C# 코드는 다음 코드 예제와 같습니다.

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) }
            }
        };
    }
}

C#에서는 인라인 DataTemplateFunc 인수를 지정하는 생성자 오버로드를 사용하여 생성됩니다.

형식과 함께 DataTemplate 만들기

ListView.ItemTemplate 속성을 셀 형식에서 만든 DataTemplate으로 설정할 수도 있습니다. 이 방법의 장점은 셀 형식으로 정의된 모양을 애플리케이션 전체에서 여러 데이터 템플릿으로 재사용할 수 있다는 것입니다. 다음 XAML 코드에서는 이 방법에 대한 예제를 보여 줍니다.

<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 속성은 셀 모양을 정의하는 사용자 지정 형식에서 생성된 DataTemplate으로 설정됩니다. 사용자 지정 형식은 다음 코드처럼 ViewCell에서 파생되어야 합니다.

<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>

ViewCell 내에서 레이아웃은 여기서 Grid로 관리됩니다. GridText 속성을 컬렉션에 있는 각 Person 개체의 적절한 속성으로 바인딩하는 세 개의 Label 인스턴스를 포함합니다.

해당하는 C# 코드가 다음 예제에 표시됩니다.

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) }
            }
        };
    }
}

C#에서는 DataTemplate이 인수로 셀 형식을 지정하는 생성자 오버로드를 사용하여 생성됩니다. 셀 형식은 다음 코드 예제처럼 ViewCell에서 파생되어야 합니다.

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;
    }
}

참고 항목

Xamarin.Forms에도 ListView 셀에 간단한 데이터를 표시하는 데 사용할 수 있는 셀 형식이 포함됩니다. 자세한 내용은 셀 모양을 참조하세요.

DataTemplate을 리소스로 만들기

데이터 템플릿은 ResourceDictionary에서 재사용 가능한 개체로 만들 수도 있습니다. 이 작업은 다음 XAML 코드 예제와 같이, ResourceDictionary에 설명적 키를 제공하는 고유한 x:Key 특성을 각 선언에 제공하여 수행합니다.

<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>

DataTemplateStaticResource 태그 확장을 사용하여 ListView.ItemTemplate 속성에 할당됩니다. DataTemplate은 페이지의 ResourceDictionary에 정의되지만 컨트롤 수준이나 애플리케이션 수준에서도 정의될 수 있습니다.

다음 코드 예제에서는 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 };
      }
    };
  }
}

DataTemplateAdd 메서드를 사용하여, 검색 시 DataTemplate을 참조하는 데 사용되는 Key 문자열을 지정하는 ResourceDictionary에 추가됩니다.

요약

이 문서에서는 사용자 지정 형식 또는 ResourceDictionary에서 데이터 템플릿, 인라인을 만드는 방법에 대해 설명했습니다. 다른 곳에서 데이터 템플릿을 다시 사용할 필요가 없으면 인라인 템플릿을 사용해야 합니다. 또는 데이터 템플릿을 사용자 지정 유형으로 정의하거나 컨트롤 수준, 페이지 수준 또는 애플리케이션 수준 리소스로 정의하여 다시 사용할 수 있습니다.