Ejercicio: Conversión de un controlador de eventos en un comando
En este ejercicio, vuelva a cambiar a la aplicación "lista de películas" con la que ha trabajado en el ejercicio anterior. Esta vez, convertirá el controlador de eventos del menú Eliminar en un comando.
Descarga y ejecución del ejemplo
- Vaya a la carpeta part6-exercise2 y abra la solución MovieCatalog.sln en Visual Studio o la carpeta de Visual Studio Code.
- Compile y ejecute el proyecto para asegurarse de que funciona. En la pantalla que se muestra, verá una lista de películas. Haga clic con el botón derecho en una de las películas enumeradas y la aplicación navega a una página de detalles.
Examen del código
Abra la solución MovieCatalog y abra el archivo Views\MovieListPage.xaml. ListView
presenta un elemento para cada película de la colección enlazada Movies
. Cada elemento define un menú contextual para eliminar una película:
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Title}" x:DataType="vm:MovieViewModel">
<TextCell.ContextActions>
<MenuItem Text="Delete" IsDestructive="True" Clicked="MenuItem_Clicked" />
</TextCell.ContextActions>
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>
Cuando se hace clic en el elemento de menú, se invoca MenuItem_Clicked
y se quita la película. El contexto de enlace del elemento de menú es la película actual, la clase MovieViewModel
. Pero el código para quitar una película está en el modelo de vista principal MovieListViewModel
de la aplicación. El controlador de eventos considera esto, ya que obtiene el contexto de enlace del elemento de menú y lo envía al método DeleteMovie
del modelo de vista:
private void MenuItem_Clicked(object sender, EventArgs e)
{
MenuItem menuItem = (MenuItem)sender;
ViewModels.MovieViewModel movie = (ViewModels.MovieViewModel)menuItem.BindingContext;
App.MainViewModel.DeleteMovie(movie);
}
Adición de un comando
El primer paso para convertir el controlador de eventos en un comando es agregar el comando al modelo de vista. Este comando acepta una película y la quita de la colección.
En la ventana Explorador de soluciones, abra el archivo ViewModels\MovieListViewModel.cs.
Agregue la siguiente propiedad a la clase
MovieListViewModel
:public ICommand DeleteMovieCommand { get; private set; }
A continuación, busque el constructor
MovieListViewModel
y cree una instancia del comando:public MovieListViewModel() { Movies = []; DeleteMovieCommand = new Command<MovieViewModel>(DeleteMovie); }
El método
DeleteMovie
ya existe y acepta un parámetroMovieViewModel
. El comando ajusta ese método y lo expone en el modelo de vista.Abra el archivo ViewModels\MoviesListPage.xaml.
Actualice
MenuItem
para enlazar el parámetroCommand
aDeleteMovieCommand
. Pase el contexto de enlace actual comoCommandParameter
.<MenuItem Text="Delete" IsDestructive="True" Command="{Binding DeleteMovieCommand, Source={x:Static local:App.MainViewModel}}" CommandParameter="{Binding}" />
Observe que el controlador de eventos
Clicked
se quitó deMenuItem
.El
Source
del contexto de enlace se establece en el modelo de vista principal de la aplicación, al igual que la propia página. El contexto de enlace deMenuItem
permanece en la película y se pasa aCommandParameter
.Abra el archivo de código subyacente para la vista, Views\MoviesListPage.xaml.cs y quite el código
MenuItem_Clicked
.Ejecute la aplicación y haga clic con el botón derecho o presione una de las películas, seleccione Eliminar en el menú contextual. La película se elimina de la lista.