연습 - 이벤트 처리기를 명령으로 변환

완료됨

이 연습에서는 이전 연습에서 작업한 “영화 목록” 앱으로 다시 전환합니다. 이번에는 삭제 메뉴의 이벤트 처리기를 명령으로 변환합니다.

샘플 다운로드 및 실행

참고 항목

Windows에서 Android의 .NET MAUI 앱을 실행하고 디버깅할 계획이라면 최대 경로 길이를 초과하는 빌드 생성 파일을 방지하기 위해 C:\dev\와 같은 짧은 폴더 경로에 연습 콘텐츠를 복제하거나 다운로드하는 것이 가장 좋습니다.

이 연습 모듈을 시작하려면 영화 목록 샘플 프로젝트를 다운로드합니다. 이 프로젝트는 영화 목록을 표시합니다. 영화를 클릭하면 영화에 대한 자세한 정보가 포함된 세부 정보 페이지로 이동합니다.

  1. 영화 목록 샘플 프로젝트를 다운로드하여 임시 폴더로 추출합니다.
  2. part6-exercise2 폴더로 이동하여 MovieCatalog.sln 솔루션을 엽니다.
  3. 프로젝트를 빌드하고 실행하여 작동하는지 확인합니다. 화면이 표시되면 영화 목록이 표시됩니다. 나열된 영화 중 하나를 마우스 오른쪽 단추로 클릭하면 앱이 세부 정보 페이지로 이동합니다.

코드 검사

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 클래스입니다. 그러나 영화를 제거하는 코드는 앱의 기본 viewmodel MovieListViewModel에 있습니다. 이벤트 처리기는 메뉴 항목의 바인딩 컨텍스트를 가져오고 viewmodel의 DeleteMovie 메서드로 전송할 때 이를 고려합니다.

private void MenuItem_Clicked(object sender, EventArgs e)
{
    MenuItem menuItem = (MenuItem)sender;
    ViewModels.MovieViewModel movie = (ViewModels.MovieViewModel)menuItem.BindingContext;
    App.MainViewModel.DeleteMovie(movie);
}

명령 추가

이벤트 처리기를 명령으로 변환하는 첫 번째 단계는 viewmodel에 명령을 추가하는 것입니다. 이 명령은 영화를 허용하고 이를 컬렉션에서 제거합니다.

  1. 솔루션 탐색기 창에서 ViewModels\MovieListViewModel.cs 파일을 엽니다.

  2. 다음 속성을 MovieListViewModel 클래스에 추가합니다.

    public ICommand DeleteMovieCommand { get; private set; }
    
  3. 다음으로, MovieListViewModel 생성자를 찾아 명령을 인스턴스화합니다.

    public MovieListViewModel()
    {
        Movies = [];
        DeleteMovieCommand = new Command<MovieViewModel>(DeleteMovie);
    }
    

    DeleteMovie 메서드가 이미 있으며 MovieViewModel 매개 변수를 허용합니다. 이 명령은 해당 메서드를 래핑하고 viewmodel에 노출합니다.

  4. ViewModels\MoviesListPage.xaml 파일을 엽니다.

  5. Command 매개 변수를 DeleteMovieCommand에 바인딩하도록 MenuItem을 업데이트합니다. 현재 바인딩 컨텍스트를 CommandParameter로 전달합니다.

    <MenuItem Text="Delete"
              IsDestructive="True"
              Command="{Binding DeleteMovieCommand, Source={x:Static local:App.MainViewModel}}"
              CommandParameter="{Binding}" />
    

    Clicked 이벤트 처리기가 MenuItem에서 제거되었습니다.

    바인딩 컨텍스트의 Source는 페이지 자체와 마찬가지로 앱의 기본 viewmodel로 설정됩니다. MenuItem의 바인딩 컨텍스트는 영화로 유지되며 이는 CommandParameter로 전달됩니다.

  6. 뷰의 코드 숨김 파일인 Views\MoviesListPage.xaml.cs를 열고 MenuItem_Clicked 코드를 제거합니다.

  7. 앱을 실행하고 영화 중 하나를 마우스 오른쪽 단추로 클릭하거나 길게 누르고 바로 가기 메뉴에서 삭제를 선택합니다. 영화가 목록에서 삭제됩니다.