演習 - イベント ハンドラーをコマンドに変換する
この演習では、前の演習で作業した "ムービー一覧" アプリに戻ります。 今回は、[削除] メニューのイベント ハンドラーをコマンドに変換します。
サンプルのダウンロードと実行
Note
Windows から Android 上の .NET MAUI アプリを実行してデバッグすることを計画している場合は、演習コンテンツを C:\dev\ のような短いフォルダー パスにクローンするかダウンロードし、ビルドによって生成されるファイルがパスの最大長を超えないようにすることをお勧めします。
この演習モジュールを開始するにあたり、Movie List Sample プロジェクトをダウンロードします。 このプロジェクトでは、ムービーの一覧が表示されます。 ムービーをクリックすると、ムービーに関する詳細情報が表示された詳細ページに移動します。
- Movie List Sample プロジェクトをダウンロードして、一時フォルダーに展開します。
- part6-exercise2 フォルダーに移動し、MovieCatalog.sln ソリューションを開きます。
- プロジェクトをビルドして実行し、プロジェクトが動作することを確認します。 表示された画面に、ムービーの一覧が表示されます。 一覧表示されているいずれかのムービーを右クリックすると、アプリが詳細ページに移動します。
コードを確認する
MovieCatalog ソリューションを開き、Views\MovieListPage.xaml ファイルを開きます。 ListView
は、バインドされた Movies
コレクション内の各ムービーの項目を表示します。 各項目によって、ムービーを削除するためのコンテキスト メニューが定義されます。
<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>
メニュー項目がクリックされると、MenuItem_Clicked
が呼び出され、ムービーが削除されます。 メニュー項目のバインディング コンテキストは、現在のムービー、MovieViewModel
クラスです。 ただし、ムービーを削除するためのコードは、アプリのメイン ビューモデル MovieListViewModel
にあります。 イベント ハンドラーは、メニュー項目のバインド コンテキストを取得し、ビューモデルの DeleteMovie
メソッドに送信するため、これを考慮します。
private void MenuItem_Clicked(object sender, EventArgs e)
{
MenuItem menuItem = (MenuItem)sender;
ViewModels.MovieViewModel movie = (ViewModels.MovieViewModel)menuItem.BindingContext;
App.MainViewModel.DeleteMovie(movie);
}
コマンドを追加する
イベント ハンドラーをコマンドに変換する最初の手順は、コマンドをビューモデルに追加することです。 このコマンドはムービーを受け取り、コレクションから削除します。
ソリューション エクスプローラー ウィンドウで、ViewModels\MovieListViewModel.cs ファイルを開きます。
MovieListViewModel
クラスに次のプロパティを追加します。public ICommand DeleteMovieCommand { get; private set; }
次に、
MovieListViewModel
コンストラクターを見つけて、コマンドをインスタンス化します。public MovieListViewModel() { Movies = []; DeleteMovieCommand = new Command<MovieViewModel>(DeleteMovie); }
DeleteMovie
メソッドは既に存在し、MovieViewModel
パラメーターを受け取ります。 このコマンドは、そのメソッドをラップし、ビューモデルで公開します。ViewModels\MoviesListPage.xaml ファイルを開きます。
Command
パラメーターをDeleteMovieCommand
にバインドするようにMenuItem
を更新します。 現在のバインディング コンテキストをCommandParameter
として渡します。<MenuItem Text="Delete" IsDestructive="True" Command="{Binding DeleteMovieCommand, Source={x:Static local:App.MainViewModel}}" CommandParameter="{Binding}" />
Clicked
イベント ハンドラーがMenuItem
から削除されていることに注意してください。バインディング コンテキストの
Source
は、ページ自体と同様に、アプリのメイン ビューモデルに設定されます。MenuItem
のバインディング コンテキストはムービーのままであり、CommandParameter
に渡されます。ビュー Views\MoviesListPage.xaml.cs の分離コード ファイルを開き、
MenuItem_Clicked
コードを削除します。アプリを実行し、いずれかのムービーを右クリックまたは長押しして、コンテキスト メニューから [削除] を選択します。 ムービーがリストから削除されます。