Introducción
Estas usando un control enlazado a una colección (por ejemplo, un listado de peliculas) y en cada elemento cuentas con un botón para añadir la pelicula a favoritos. Por defecto, cada elemento tendra como contexto la pelicula de la colección enlazada al listado y añadir un comando en cada elemento no suena como la mejor idea pero…¿que hacemos en este caso?.
RelativeSource
Contábamos ya con otras soluciones para hacer Binding a un elemento visual (x:Reference) pero nos llega RelativeSource, la solución ideal en casos como el anterior.
RelativeSource es una extensión de marcado que se utiliza en casos de enlace particulares cuando intentamos vincular una propiedad de un objeto a otro de sus padres relativos.
Veamoslo con un ejemplo sencillo. Vamos a trabajar con tareas:
public class TodoItem { public string Name { get; set; } public string Description { get; set; } public bool IsDone { get; set; } }
De modo que en la ViewModel contaremos con un listado de tareas:
Items = new ObservableCollection<TodoItem> { new TodoItem { Name = "Create RelativeSource Demo" }, new TodoItem { Name = "Buy Milk" }, new TodoItem { Name = "Go for a walk" } };
Y un comando:
public ICommand DeleteTodoItemCommand => new Command<TodoItem>(DeleteTodoItem);
NOTA: Fíjate que cada TodoItem no cuenta con un comando.
En la interfaz de usuario:
<ListView ItemsSource="{Binding Items}"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="80" /> </Grid.ColumnDefinitions> <Label Grid.Column="0" Text="{Binding Name}"/> <Button Grid.Column="1" Text="Delete" CommandParameter="{Binding}" Command="{Binding Source={RelativeSource AncestorType={x:Type viewModels:MainViewModel}}, Path=DeleteTodoItemCommand}"/> </Grid> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView>
El resultado:
El comando hace uso de RelativeSource para acceder al ancestro de tipo MainViewModel y Path, el comando.
Puedes encontrar el código del ejemplo en GitHub:
Otra extensión de marcada añadida que viene a solucionar ciertos casos. ¿Qué te parece el añadido?.
Recuerda, cualquier comentario o feedback es bienvenido en los comentarios de la entrada.
Más información
- GitHub: RelativeSource Binding
Reblogueó esto en El Bruno.
Nice