ContentView de Xamarin.Forms
La clase Xamarin.FormsContentView
es un tipo de Layout
que contiene un único elemento secundario y se usa normalmente para crear controles personalizados y reutilizables. La clase ContentView
se hereda de TemplatedView
. En este artículo, y en el ejemplo correspondiente, se explica cómo crear un control CardView
personalizado basado en la clase ContentView
.
En la captura de pantalla siguiente se muestra un control CardView
que se deriva de la clase ContentView
:
La clase ContentView
define una sola propiedad:
Content
es un objetoView
. Esta propiedad está respaldada por un objetoBindableProperty
para que pueda ser el destino de los enlaces de datos.
ContentView
también hereda una propiedad de la clase TemplatedView
:
ControlTemplate
es unControlTemplate
que puede definir o invalidar la apariencia del control.
Para obtener más información sobre la propiedad ControlTemplate
, consulta Personalización de la apariencia con ControlTemplate.
Creación de un control personalizado
La clase ContentView
ofrece poca funcionalidad por sí misma, pero se puede usar para crear un control personalizado. El proyecto de ejemplo define un control CardView
: un elemento de interfaz de usuario que muestra una imagen, un título y una descripción en un diseño similar a una tarjeta.
El proceso para crear un control personalizado es para:
- Cree una nueva clase usando la plantilla
ContentView
en Visual Studio 2019. - Defina las propiedades o eventos únicos del archivo de código subyacente para el nuevo control personalizado.
- Cree la interfaz de usuario para el control personalizado.
Nota:
Es posible crear un control personalizado cuyo diseño se defina en código en lugar de hacerlo con XAML. Por motivos de simplicidad, la aplicación de ejemplo solo define una sola clase CardView
con un diseño XAML. Sin embargo, la aplicación de ejemplo contiene una clase CardViewCodePage que muestra el proceso de consumo del control personalizado en el código.
Creación de propiedades de código subyacente
El control personalizado CardView
define las siguientes propiedades:
CardTitle
: un objetostring
que representa el título que se muestra en la tarjeta.CardDescription
: un objetostring
que representa la descripción que se muestra en la tarjeta.IconImageSource
: un objetoImageSource
que representa la imagen que se muestra en la tarjeta.IconBackgroundColor
: un objetoColor
que representa el color de fondo de la imagen que se muestra en la tarjeta.BorderColor
: un objetoColor
que representa el color del borde de la tarjeta, el borde de imagen y la línea divisora.CardColor
: un objetoColor
que representa el color de fondo de la tarjeta.
Nota:
La propiedad BorderColor
afecta a varios elementos con fines de demostración. Esta propiedad podría dividirse en tres propiedades si es necesario.
Cada propiedad está respaldada por una instancia de BindableProperty
. La BindableProperty
de respaldo permite aplicar un estilo a cada propiedad y enlazarla mediante el patrón MVVM.
En el ejemplo siguiente se muestra cómo crear una BindableProperty
de respaldo:
public static readonly BindableProperty CardTitleProperty = BindableProperty.Create(
"CardTitle", // the name of the bindable property
typeof(string), // the bindable property type
typeof(CardView), // the parent object type
string.Empty); // the default value for the property
La propiedad personalizada usa los métodos GetValue
y SetValue
para obtener y establecer los valores del objeto BindableProperty
:
public string CardTitle
{
get => (string)GetValue(CardView.CardTitleProperty);
set => SetValue(CardView.CardTitleProperty, value);
}
Para obtener más información sobre los objetos BindableProperty
, consulte Propiedades enlazables.
Definición de la interfaz de usuario
La interfaz de usuario de control personalizada usa ContentView
como elemento raíz para el control CardView
. En el ejemplo siguiente se muestra el XAML de CardView
:
<ContentView ...
x:Name="this"
x:Class="CardViewDemo.Controls.CardView">
<Frame BindingContext="{x:Reference this}"
BackgroundColor="{Binding CardColor}"
BorderColor="{Binding BorderColor}"
...>
<Grid>
...
<Frame BorderColor="{Binding BorderColor, FallbackValue='Black'}"
BackgroundColor="{Binding IconBackgroundColor, FallbackValue='Grey'}"
...>
<Image Source="{Binding IconImageSource}"
.. />
</Frame>
<Label Text="{Binding CardTitle, FallbackValue='Card Title'}"
... />
<BoxView BackgroundColor="{Binding BorderColor, FallbackValue='Black'}"
... />
<Label Text="{Binding CardDescription, FallbackValue='Card description text.'}"
... />
</Grid>
</Frame>
</ContentView>
El elemento ContentView
establece la propiedad x:Name
en this, que se puede usar para acceder al objeto enlazado a la instancia CardView
. Los elementos del conjunto de diseño enlazan sus propiedades a los valores definidos en el objeto enlazado.
Para obtener más información sobre el enlace de datos, consulte Enlace de datos de Xamarin.Forms.
Nota:
La propiedad FallbackValue
proporciona un valor predeterminado en caso de que el enlace sea null
. Esto también permite que el controlador de vista previa XAML de Visual Studio represente el control CardView
.
Creación de instancias de un control personalizado
Se debe agregar una referencia al espacio de nombres de control personalizado a una página que cree una instancia del control personalizado. En el ejemplo siguiente se muestra una referencia de espacio de nombres denominada controls que se agrega a una instancia de ContentPage
en XAML:
<ContentPage ...
xmlns:controls="clr-namespace:CardViewDemo.Controls" >
Una vez agregada la referencia, se puede crear una instancia de CardView
en XAML y se pueden definir sus propiedades:
<controls:CardView BorderColor="DarkGray"
CardTitle="Slavko Vlasic"
CardDescription="Lorem ipsum dolor sit..."
IconBackgroundColor="SlateGray"
IconImageSource="user.png"/>
También se puede crear una instancia de CardView
en el código:
CardView card = new CardView
{
BorderColor = Color.DarkGray,
CardTitle = "Slavko Vlasic",
CardDescription = "Lorem ipsum dolor sit...",
IconBackgroundColor = Color.SlateGray,
IconImageSource = ImageSource.FromFile("user.png")
};
Personalización de la apariencia con ControlTemplate
Un control personalizado que deriva de la clase ContentView
puede definir la apariencia mediante XAML, código o puede que no defina la apariencia en absoluto. Independientemente de cómo se defina la apariencia, un objeto ControlTemplate
puede invalidar la apariencia con un diseño personalizado.
El diseño CardView
puede ocupar demasiado espacio para algunos casos de uso. Un ControlTemplate
puede invalidar el diseño CardView
para proporcionar una vista más compacta, adecuada para una lista condensada:
<ContentPage.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="CardViewCompressed">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100*" />
</Grid.ColumnDefinitions>
<Image Grid.Row="0"
Grid.Column="0"
Source="{TemplateBinding IconImageSource}"
BackgroundColor="{TemplateBinding IconBackgroundColor}"
WidthRequest="100"
HeightRequest="100"
Aspect="AspectFill"
HorizontalOptions="Center"
VerticalOptions="Center"/>
<StackLayout Grid.Row="0"
Grid.Column="1">
<Label Text="{TemplateBinding CardTitle}"
FontAttributes="Bold" />
<Label Text="{TemplateBinding CardDescription}" />
</StackLayout>
</Grid>
</ControlTemplate>
</ResourceDictionary>
</ContentPage.Resources>
El enlace de datos de ControlTemplate
usa la extensión de marcado TemplateBinding
para especificar enlaces. A continuación, la propiedad ControlTemplate
se puede establecer en el objeto ControlTemplate definido usando su valor x:Key
. En el siguiente ejemplo se muestra la propiedad ControlTemplate
establecida en la instancia CardView
:
<controls:CardView ControlTemplate="{StaticResource CardViewCompressed}"/>
Las capturas de pantalla siguientes muestran una instancia estándar de CardView
y CardView
cuyo ControlTemplate
se ha invalidado:
Para obtener más información sobre las plantillas de control, consulte Plantillas de control de Xamarin.Forms.