Qué es x:Reference
Es una de las mejores características que se pueden usar cuando usamos XAML. usando x:Reference se pueden enlazar propiedades de dos vistas en la misma pagina. Hay un montón de casos en los que podemos usar esta característica.
Aquí vamos con unos cuantos ejemplos:
1- Sí estamos usando un ListView sabemos que el BindingContext dentro del ViewCell es el elemento de la lista. Pero que pasa si queremos cambiar una propiedad específica de acuerdo con el ViewModel. con x:Reference podemos dar solución a este problema fácilmente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); BindingContext = new MainPageViewModel(); } } public class MainPageViewModel { public ObservableCollection<Coche> Coches{ get; set; } public bool EstaActivo { get; set; } public MainPageViewModel() { Coches.Add(new Coche() { Marca = "Toyota", Modelo = "Prius" }); Coches.Add(new Coche() { Marca = "Seat", Modelo = "León" }); } } public class Coche { public string Marca { get; set; } public string Modelo { get; set; } } |
Como podemos ver aquí en el ViewModel hay una propiedad llamada «EstaActivo», si esta propiedad es verdadera mostraremos el texto «Esta Activo» en cada elemento de la celda.
Primer contacto
El BindingContext de la pagina es el ViewModel así que vamos a hacer lo siguiente.
1- Añadir x:Name en la capa principal de la pagina la cual es establecida al ViewModel.
2- Añadir el icono en el ViewCell y usando la propiedad BindingContext establecida al BindingContext de x:Name que hemos añadido anteriormente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:CrossReference" xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core" ios:Page.UseSafeArea="true" x:Class="CrossReference.MainPage"> <StackLayout x:Name="mainLayou"> <ListView ItemsSource="{Binding Coches}" VerticalOptions="Fill" RowHeight="200"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout> <Label Text="{Binding Marca}" /> <Label Text="{Binding Modelo}" /> <Label Text="Esta Activo" BindingContext="{Binding Path=BindingContext, Source={x:Reference mainLayout}}" IsVisible="{Biding EstaActivo}" /> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackLayout> </ContentPage> |
Como podemos ver la sintaxis es realmente sencilla, usando la propierdad Source=»{x:Reference x:NombreElemento}» para especificar la propiedad a la que queremos referenciar. Podemos usar la propiedad Path para usar una propiedad especifica de ese elemento y no él elemento entero.
Desde el ViewModel
Si no queremos usar la propiedad BindingContext podemos usar cualquier propiedad. Por ejemplo, podemos ejecutar un comando (Command) en el ViewModel desde el ViewCell.
1 2 3 4 5 6 7 8 9 10 11 12 |
public ICommand DeleteCommand { get; set; } public MainPageViewModel() { Coches.Add(new Coche() { Marca = "Toyota", Modelo = "Prius" }); Coches.Add(new Coche() { Marca = "Seat", Modelo = "León" }); DeleteCommand = new Command<Coche>((obj) => { Coches.Remove(obj); }); } |
El ViewCell del ListView quedaría de la siguiente forma en el archivo XAML.
1 2 3 4 5 6 7 8 9 10 11 12 |
<ViewCell> <StackLayout> <Label Text="{Binding Marca}" /> <Label Text="{Binding Modelo}" /> <Label Text="Esta Activo" BindingContext="{Binding Path=BindingContext, Source={x:Reference mainLayout}}" IsVisible="{Biding EstaActivo}" > <Label.GestureRecognizers> <TapGestureRecognizer Command="{Binding Path=BindingContext.DeleteCommand, Source={x:Reference mainLayout}}" CommandParameter="{Binding .}" /> </Label.GestureRecognizers> </Label> </StackLayout> </ViewCell> |
A veces XAML por desconocimiento resulta más dificil de lo habitual descubrir sus funcionalidades y apreciar su potencia, no obtante, aqui os dejo algun truco más sobre etiquetas en xaml.