ObservableObject
및 ObservableObject
인터페이스를 구현하여 관찰할 수 있는 개체의 INotifyPropertyChanged
INotifyPropertyChanging
기본 클래스입니다. 속성 변경 알림을 지원해야 하는 모든 종류의 개체에 대한 시작점으로 사용할 수 있습니다.
플랫폼 API:
ObservableObject
, ,TaskNotifier
TaskNotifier<T>
작동 방식
ObservableObject
에는 다음과 같은 주요 기능이 있습니다.
- 또한 이벤트 및
INotifyPropertyChanging
이벤트를 노출하는 기본 구현INotifyPropertyChanged
을PropertyChanged
PropertyChanging
제공합니다. - 상속되는 형식
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 도구 키트를 확인합니다.
- 단위 테스트에서 더 많은 예제를 찾을 수도 있습니다.
MVVM Toolkit