다음을 통해 공유


ObservableObject

ObservableObject 인터페이스를 구현하여 관찰할 수 있는 개체의 INotifyPropertyChangedINotifyPropertyChanging 기본 클래스입니다. 속성 변경 알림을 지원해야 하는 모든 종류의 개체에 대한 시작점으로 사용할 수 있습니다.

플랫폼 API:ObservableObject, TaskNotifierTaskNotifier<T>

작동 방식

ObservableObject에는 다음과 같은 기본 기능이 있습니다.

  • 또한 이벤트 및 INotifyPropertyChanging이벤트를 노출하는 기본 구현 INotifyPropertyChangedPropertyChangedPropertyChanging 제공합니다.
  • 상속되는 형식ObservableObject에서 SetProperty 속성 값을 쉽게 설정하고 적절한 이벤트를 자동으로 발생시키는 데 사용할 수 있는 일련의 메서드를 제공합니다.
  • 할당된 작업이 완료될 때 속성을 설정하고 Task 알림 이벤트를 자동으로 발생시키는 기능과 유사하지만 유사한 SetProperty 메서드를 제공합니다SetPropertyAndNotifyOnCompletion.
  • 알림 이벤트가 발생하는 방식을 사용자 지정하기 위해 파생 형식에서 재정의할 수 있는 메서드 및 OnPropertyChanging 메서드를 노출 OnPropertyChanged 합니다.

단순 속성

다음은 사용자 지정 속성에 대한 알림 지원을 구현하는 방법의 예입니다.

public class User : ObservableObject
{
    private string name;

    public string Name
    {
        get => name;
        set => SetProperty(ref name, value);
    }
}

제공된 SetProperty<T>(ref T, T, string) 메서드는 속성의 현재 값을 검사 다른 경우 업데이트한 다음 관련 이벤트도 자동으로 발생합니다. 속성 이름은 특성을 사용하여 [CallerMemberName] 자동으로 캡처되므로 업데이트할 속성을 수동으로 지정할 필요가 없습니다.

관찰할 수 없는 모델 래핑

예를 들어 데이터베이스 항목을 사용할 때 일반적인 시나리오는 데이터베이스 모델의 속성을 릴레이하고 필요할 때 속성 변경 알림을 발생시키는 래핑 "바인딩 가능" 모델을 만드는 것입니다. 인터페이스를 구현 INotifyPropertyChanged 하지 않는 모델에 알림 지원을 삽입하려는 경우에도 필요합니다. ObservableObject 는 이 프로세스를 더 간단하게 만드는 전용 메서드를 제공합니다. 다음 예제 User 에서는 다음에서 ObservableObject상속하지 않고 데이터베이스 테이블을 직접 매핑하는 모델입니다.

public class ObservableUser : ObservableObject
{
    private readonly User user;

    public ObservableUser(User user) => this.user = user;

    public string Name
    {
        get => user.Name;
        set => SetProperty(user.Name, value, user, (u, n) => u.Name = n);
    }
}

이 경우 오버로드를 SetProperty<TModel, T>(T, T, TModel, Action<TModel, T>, string) 사용하고 있습니다. 서명은 이전 시나리오보다 약간 더 복잡합니다. 이전 시나리오와 같이 지원 필드에 액세스할 수 없더라도 코드가 여전히 매우 효율적일 수 있도록 해야 합니다. 이 메서드 서명의 각 부분을 자세히 살펴보고 다양한 구성 요소의 역할을 이해할 수 있습니다.

  • TModel 는 래핑할 모델의 형식을 나타내는 형식 인수입니다. 이 경우 클래스 User 가 됩니다. 이를 명시적으로 지정할 필요가 없습니다. C# 컴파일러는 메서드를 호출하는 SetProperty 방법에 따라 이를 자동으로 유추합니다.
  • T 은 설정하려는 속성의 형식입니다. 마찬가지로 TModel, 자동으로 유추됩니다.
  • T oldValue 는 첫 번째 매개 변수이며, 이 경우 래핑하는 해당 속성의 현재 값을 전달하는 데 사용합니다 user.Name .
  • T newValue 는 속성으로 설정할 새 값이며, 여기서는 속성 setter 내의 입력 값인 전달 value합니다.
  • TModel model 는 래핑하는 대상 모델입니다. 이 경우 필드에 저장된 인스턴스를 user 전달합니다.
  • Action<TModel, T> callback 는 속성의 새 값이 현재 값과 다르고 속성을 설정해야 하는 경우 호출되는 함수입니다. 이 작업은 대상 모델 및 설정할 새 속성 값을 입력으로 수신하는 이 콜백 함수에 의해 수행됩니다. 이 경우 입력 값(호출 n한 값)을 속성에 할당합니다 Name (수행 u.Name = n). C# 컴파일러가 콜백 함수를 캐시하고 여러 가지 성능 향상을 수행할 수 있으므로 현재 범위에서 값을 캡처하지 않고 콜백에 대한 입력으로 지정된 값과만 상호 작용하는 것이 중요합니다. 이 때문에 여기서 필드 또는 value setter의 매개 변수에 직접 액세스하는 user 것이 아니라 람다 식에 대한 입력 매개 변수만 사용합니다.

SetProperty<TModel, T>(T, T, TModel, Action<TModel, T>, string) 메서드는 매우 간단한 API를 제공하면서 대상 속성을 검색하고 설정하는 것을 모두 처리하므로 이러한 래핑 속성을 매우 간단하게 만듭니다.

참고 항목

LINQ 식을 사용하는 이 메서드의 구현과 비교할 때, 특히 상태 및 콜백 매개 변수 대신 형식 Expression<Func<T>> 의 매개 변수를 통해 이러한 방식으로 달성할 수 있는 성능 향상은 매우 중요합니다. 특히 이 버전은 LINQ 식을 사용하는 버전보다 ~200배 빠르며 메모리 할당을 전혀 수행하지 않습니다.

Task<T> 속성 처리

속성인 Task 경우 작업이 완료되면 알림 이벤트도 발생시켜 바인딩이 적시에 업데이트되도록 해야 합니다. 예를 들어 태스크가 나타내는 작업에 대한 로드 표시기 또는 기타 상태 정보를 표시합니다. ObservableObject 이 시나리오에 대한 API가 있습니다.

public class MyModel : ObservableObject
{
    private TaskNotifier<int>? requestTask;

    public Task<int>? RequestTask
    {
        get => requestTask;
        set => SetPropertyAndNotifyOnCompletion(ref requestTask, value);
    }

    public void RequestValue()
    {
        RequestTask = WebService.LoadMyValueAsync();
    }
}

SetPropertyAndNotifyOnCompletion<T>(ref TaskNotifier<T>, Task<T>, string) 여기서 메서드는 대상 필드 업데이트, 새 작업 모니터링( 있는 경우) 및 해당 작업이 완료될 때 알림 이벤트를 발생시키는 작업을 처리합니다. 이렇게 하면 작업 속성에 바인딩하고 상태 변경될 때 알림을 받을 수 있습니다. 대상 TaskNotifier<T> 인스턴스를 래핑하고 이 메서드에 ObservableObject 필요한 알림 논리를 Task<T> 사용하도록 설정하는 특수 형식입니다. TaskNotifier 일반 Task 만 있는 경우 직접 사용할 수 있는 형식도 있습니다.

참고 항목

메서드 SetPropertyAndNotifyOnCompletion 는 패키지에서 형식의 NotifyTaskCompletion<T> 사용을 대체 하기 위한 것입니다 Microsoft.Toolkit . 이 형식을 사용 중인 경우 내부 Task (또는 Task<TResult>) 속성으로 바꿀 수 있으며 SetPropertyAndNotifyOnCompletion 메서드를 사용하여 값을 설정하고 알림 변경을 발생할 수 있습니다. 형식에 의해 NotifyTaskCompletion<T> 노출되는 모든 속성은 인스턴스에서 Task 직접 사용할 수 있습니다.

예제

  • 샘플 앱(여러 UI 프레임워크의 경우)을 확인하여 작동 중인 MVVM 도구 키트를 확인합니다.
  • 단위 테스트에서 더 많은 예제를 찾을 수도 있습니다.