Compartir vía


Genéricos en Xamarin.Forms XAML

Xamarin.Forms XAML proporciona compatibilidad para consumir tipos CLR genéricos especificando las restricciones genéricas como argumentos de tipo. Esta compatibilidad la proporciona la directiva x:TypeArguments, que pasa los argumentos de tipo restrictivo de un genérico al constructor del tipo genérico.

Importante

No se admite la definición de clases genéricas en Xamarin.Forms XAML con la directiva x:TypeArguments.

Los argumentos de tipo se especifican como una cadena y suelen llevar prefijos, como sys:String y sys:Int32. El prefijo es necesario porque los tipos típicos de restricciones genéricas CLR proceden de bibliotecas que no están asignadas al espacio de nombres predeterminado Xamarin.Forms. Sin embargo, los tipos integrados de XAML 2009, como x:String y x:Int32, también se pueden especificar como argumentos de tipo, donde x es el espacio de nombres del lenguaje XAML para XAML 2009. Para obtener más información sobre los tipos integrados de XAML 2009, consulta Primitivas del lenguaje XAML 2009.

Se pueden especificar varios argumentos de tipo mediante un delimitador de comas. Además, si una restricción genérica usa tipos genéricos, los argumentos de tipo de restricción anidados deben ir entre paréntesis.

Nota:

La extensión de marcado x:Type proporciona una referencia de tipo CLR para un tipo genérico y tiene una función similar al operador typeof en C#. Para obtener más información, consulta Extensión de marcado x:Type.

Argumento de tipo primitivo único

Se puede especificar un único argumento de tipo primitivo como argumento de cadena con prefijo con la directiva x:TypeArguments:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:scg="clr-namespace:System.Collections.Generic;assembly=netstandard"
             ...>
    <CollectionView>
        <CollectionView.ItemsSource>
            <scg:List x:TypeArguments="x:String">
                <x:String>Baboon</x:String>
                <x:String>Capuchin Monkey</x:String>
                <x:String>Blue Monkey</x:String>
                <x:String>Squirrel Monkey</x:String>
                <x:String>Golden Lion Tamarin</x:String>
                <x:String>Howler Monkey</x:String>
                <x:String>Japanese Macaque</x:String>
            </scg:List>
        </CollectionView.ItemsSource>
    </CollectionView>
</ContentPage>

En este ejemplo, System.Collections.Generic se define como el espacio de nombres XAML scg. La propiedad CollectionView.ItemsSource se establece en un objeto List<T> del que se crea una instancia con un argumento de tipo string, usando el tipo x:String integrado en XAML 2009. La colección List<string> se inicializa con múltiples elementos string.

Como alternativa, pero de forma equivalente, se puede crear una instancia de la colección List<T> con el tipo CLR String:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:scg="clr-namespace:System.Collections.Generic;assembly=netstandard"
             xmlns:sys="clr-namespace:System;assembly=netstandard"
             ...>
    <CollectionView>
        <CollectionView.ItemsSource>
            <scg:List x:TypeArguments="sys:String">
                <sys:String>Baboon</sys:String>
                <sys:String>Capuchin Monkey</sys:String>
                <sys:String>Blue Monkey</sys:String>
                <sys:String>Squirrel Monkey</sys:String>
                <sys:String>Golden Lion Tamarin</sys:String>
                <sys:String>Howler Monkey</sys:String>
                <sys:String>Japanese Macaque</sys:String>
            </scg:List>
        </CollectionView.ItemsSource>
    </CollectionView>
</ContentPage>

Argumento de tipo de objeto único

Se puede especificar un único argumento de tipo de objeto como argumento de cadena con prefijo con la directiva x:TypeArguments:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:models="clr-namespace:GenericsDemo.Models"
             xmlns:scg="clr-namespace:System.Collections.Generic;assembly=netstandard"
             ...>
    <CollectionView>
        <CollectionView.ItemsSource>
            <scg:List x:TypeArguments="models:Monkey">
                <models:Monkey Name="Baboon"
                               Location="Africa and Asia"
                               ImageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg" />
                <models:Monkey Name="Capuchin Monkey"
                               Location="Central and South America"
                               ImageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Capuchin_Costa_Rica.jpg/200px-Capuchin_Costa_Rica.jpg" />
                <models:Monkey Name="Blue Monkey"
                               Location="Central and East Africa"
                               ImageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/BlueMonkey.jpg/220px-BlueMonkey.jpg" />
            </scg:List>
        </CollectionView.ItemsSource>
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid Padding="10">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Image Grid.RowSpan="2"
                           Source="{Binding ImageUrl}"
                           Aspect="AspectFill"
                           HeightRequest="60"
                           WidthRequest="60" />
                    <Label Grid.Column="1"
                           Text="{Binding Name}"
                           FontAttributes="Bold" />
                    <Label Grid.Row="1"
                           Grid.Column="1"
                           Text="{Binding Location}"
                           FontAttributes="Italic"
                           VerticalOptions="End" />
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>

En este ejemplo, GenericsDemo.Models se define como el espacio de nombres XAML models, y System.Collections.Generic se define como el espacio de nombres XAML scg. La propiedad CollectionView.ItemsSource se establece en un objeto List<T> del que se crea una instancia con un argumento de tipo Monkey. La colección List<Monkey> se inicializa con múltiples elementos Monkey, y un objeto DataTemplate que define la apariencia de cada objeto Monkey se establece como ItemTemplate de CollectionView.

Varios argumentos de tipo

Se pueden especificar varios argumentos de tipo como argumentos de cadena con prefijo, delimitados por una coma, con la directiva x:TypeArguments. Cuando una restricción genérica usa tipos genéricos, los argumentos de tipo de restricción anidados se contienen entre paréntesis:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:models="clr-namespace:GenericsDemo.Models"
             xmlns:scg="clr-namespace:System.Collections.Generic;assembly=netstandard"
             ...>
    <CollectionView>
        <CollectionView.ItemsSource>
            <scg:List x:TypeArguments="scg:KeyValuePair(x:String,models:Monkey)">
                <scg:KeyValuePair x:TypeArguments="x:String,models:Monkey">
                    <x:Arguments>
                        <x:String>Baboon</x:String>
                        <models:Monkey Location="Africa and Asia"
                                       ImageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg" />
                    </x:Arguments>
                </scg:KeyValuePair>
                <scg:KeyValuePair x:TypeArguments="x:String,models:Monkey">
                    <x:Arguments>
                        <x:String>Capuchin Monkey</x:String>
                        <models:Monkey Location="Central and South America"
                                       ImageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Capuchin_Costa_Rica.jpg/200px-Capuchin_Costa_Rica.jpg" />   
                    </x:Arguments>
                </scg:KeyValuePair>
                <scg:KeyValuePair x:TypeArguments="x:String,models:Monkey">
                    <x:Arguments>
                        <x:String>Blue Monkey</x:String>
                        <models:Monkey Location="Central and East Africa"
                                       ImageUrl="https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/BlueMonkey.jpg/220px-BlueMonkey.jpg" />
                    </x:Arguments>
                </scg:KeyValuePair>
            </scg:List>
        </CollectionView.ItemsSource>
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid Padding="10">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Image Grid.RowSpan="2"
                           Source="{Binding Value.ImageUrl}"
                           Aspect="AspectFill"
                           HeightRequest="60"
                           WidthRequest="60" />
                    <Label Grid.Column="1"
                           Text="{Binding Key}"
                           FontAttributes="Bold" />
                    <Label Grid.Row="1"
                           Grid.Column="1"
                           Text="{Binding Value.Location}"
                           FontAttributes="Italic"
                           VerticalOptions="End" />
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage    

En este ejemplo, GenericsDemo.Models se define como el espacio de nombres XAML models, y System.Collections.Generic se define como el espacio de nombres XAML scg. La propiedad CollectionView.ItemsSource se establece en un objeto List<T> del que se crea una instancia con la restricción KeyValuePair<TKey, TValue>, con los argumentos de tipo de restricción interna string y Monkey. La colección List<KeyValuePair<string,Monkey>> se inicializa con múltiples elementos KeyValuePair, con el constructor no predeterminado KeyValuePair, y un objeto DataTemplate que define la apariencia de cada objeto Monkey se establece como ItemTemplate de CollectionView. Para obtener información sobre cómo pasar argumentos a un constructor no predeterminado, vea Paso de argumentos de constructor.