요약 - 18장. MVVM

Download Sample 샘플 다운로드

참고 항목

이 책은 2016년 봄에 출간되었으며, 그 후로 업데이트되지 않았습니다. 이 책의 많은 내용이 지금까지도 무척 유용하나, 일부 내용은 오래되었고 올바르지 않거나 완전하지 않은 주제도 있습니다.

애플리케이션을 설계하는 최상의 방법 중 하나는 종종 비즈니스 논리라고 부르는 기본 코드와 사용자 인터페이스를 분리하는 것입니다. 몇 가지 기술들이 있지만 XAML 기반 환경에 맞게 조정된 방식을 Model-View-ViewModel 또는 MVVM이라고 부릅니다.

MVVM 상호 관계

MVVM 애플리케이션에는 세 가지 레이어가 있습니다.

  • Model은 파일 또는 웹 액세스를 통해 기본 데이터를 제공합니다.
  • View는 일반적으로 XAML로 구현되는 사용자 인터페이스 또는 프레젠테이션 레이어입니다.
  • ViewModel은 Model과 View를 연결합니다.

Model은 ViewModel을 무시하고 ViewModel은 View를 무시합니다. 이러한 3개 레이어는 일반적으로 다음과 같은 메커니즘에 따라 서로 연결됩니다.

View, ViewModel, and View

많은 소규모 프로그램(및 심지어 대규모 프로그램)에서는 Model이 없거나 해당 기능이 ViewModel에 통합된 경우가 많습니다.

ViewModel 및 데이터 바인딩

데이터 바인딩에 참여하기 위해서는 ViewModel이 ViewModel의 속성 변경 시점을 View에 알릴 수 있어야 합니다. ViewModel은 System.ComponentModel 네임스페이스에서 INotifyPropertyChanged 인터페이스를 구현하여 이를 수행합니다. 이것은 Xamarin.Forms가 아닌 .NET의 일부입니다. (일반적으로 ViewModel은 플랫폼 독립성을 유지 관리하려고 시도합니다.)

INotifyPropertyChanged 인터페이스는 변경된 속성을 나타내는 PropertyChanged라는 단일 이벤트를 선언합니다.

ViewModel 시계

Xamarin.FormsBook.Toolkit 라이브러리의 DateTimeViewModel은 타이머를 기준으로 변경되는 DateTime 형식의 속성을 정의합니다. 이 클래스는 DateTime 속성이 변경될 때마다 INotifyPropertyChanged를 구현하고 PropertyChanged 이벤트를 발생시킵니다.

MvvmClock 샘플은 이 ViewModel을 인스턴스화하고 ViewModel에 대해 데이터 바인딩을 사용하여 업데이트된 날짜 및 시간 정보를 표시합니다.

ViewModel의 대화형 속성

ViewModel의 속성은 SimpleMultiplier 샘플에 속하는 SimpleMultiplierViewModel 클래스로 표시된 것처럼 더 대화형일 수 있습니다. 데이터 바인딩은 2개의 Slider 요소로부터 피승수 및 승수 값을 제공하고 Label이 포함된 제품을 표시합니다. 하지만 ViewModel 또는 코드 숨김 파일을 결과적으로 변경하지 않고도 XAML에서 이 사용자 인터페이스를 광범위하게 변경할 수 있습니다.

색 ViewModel

Xamarin.FormsBook.Toolkit 라이브러리의 ColorViewModel은 RGB 및 HSL 색 모델을 통합합니다. 이에 대해서는 HslSliders 샘플을 참조하십시오.

Triple screenshot of TK

ViewModel 스트리밍

ViewModel의 코드는 호출 속성 이름을 자동으로 가져오는 CallerMemberName 특성을 사용해서 OnPropertyChanged 메서드를 정의하여 스트리밍될 수 있습니다. Xamarin.FormsBook.Toolkit 라이브러리의 ViewModelBase 클래스가 이를 수행하고 ViewModel에 대한 기본 클래스를 제공합니다.

명령 인터페이스

MVVM은 데이터 바인딩으로 작동하고, 데이터 바인딩은 속성으로 작동합니다. 따라서 MVVM은 ButtonClicked 이벤트 또는 TapGestureRecognizerTapped 이벤트를 처리할 때 결함이 있는 것으로 보입니다. ViewModel이 이러한 이벤트를 처리할 수 있도록 Xamarin.Forms에서 명령 인터페이스가 지원됩니다.

명령 인터페이스는 다음 두 가지 공용 속성을 사용해서 Button에서 스스로 매니페스트합니다.

명령 인터페이스를 지원하기 위해서는 ViewModel이 ButtonCommand 속성에 바인딩된 데이터인 ICommand 형식의 속성을 정의해야 합니다. ICommand 인터페이스는 두 가지 메서드와 하나의 이벤트를 선언합니다.

내부적으로 ViewModel은 ICommand 형식의 각 속성을 ICommand 인터페이스를 구현하는 클래스의 인스턴스로 설정합니다. 데이터 바인딩을 통해 Button은 초기에 CanExecute 메서드를 호출하고, 메서드가 false를 반환하면 자신을 사용하지 않도록 설정합니다. 또한 CanExecuteChanged 이벤트에 대해 처리기를 설정하고 이 이벤트가 발생할 때마다 CanExecute를 호출합니다. Button이 사용하도록 설정되었으면 Button이 클릭될 때마다 Execute 메서드를 호출합니다.

Xamarin.Forms보다 앞선 ViewModel이 있을 수 있으며, 명령 인터페이스를 이미 지원할 수 있습니다. Xamarin.Forms에서만 사용하도록 의도된 새 ViewModel에 대해 Xamarin.Forms는 ICommand 인터페이스를 구현하는 Command 클래스 및 Command<T> 클래스를 제공합니다. 제네릭 형식은 ExecuteCanExecute 메서드에 대한 인수 형식입니다.

간단한 메서드 실행

PowersOfThree 샘플은 ViewModel에서 명령 인터페이스를 사용하는 방법을 보여줍니다. PowersViewModel 클래스는 ICommand 형식의 두 속성을 정의하고 가장 간단한 Command 생성자로 전달하는 2개의 프라이빗 속성도 정의합니다. 이 프로그램에는 이 ViewModel에서 두 Button 요소의 Command 속성으로의 데이터 바인딩이 포함됩니다.

Button 요소는 코드 변경 없이 XAML의 TapGestureRecognizer 개체로 쉽게 교체될 수 있습니다.

거의 계산기

AddingMachine 샘플은 ICommandExecuteCanExecute 메서드를 모두 사용합니다. Xamarin.FormsBook.Toolkit 라이브러리의 AdderViewModel 클래스를 사용합니다. ViewModel에는 ICommand 형식의 6개 속성이 포함됩니다. 이것들은 Command 생성자, CommandCommand 생성자Command<T>Command<T> 생성자로부터 초기화됩니다. 더하기 머신의 숫자 키는 모두 Command<T>로 초기화되는 속성에 바인딩되며, ExecuteCanExecute에 대한 string 인수는 특정 키를 식별합니다.

ViewModels 및 애플리케이션 수명 주기

AddingMachine 샘플에 사용되는 AdderViewModel은 또한 SaveStateRestoreState라는 두 메서드를 정의합니다. 이러한 메서드는 절전 모드로 전환될 때 그리고 다시 시작될 때 애플리케이션에서 호출됩니다.