Avalonia는 WPF의 속성 시스템을 단순히 복제한 것이 아니라, 이를 확장하여 개선했습니다.
WPF에서 대부분의 고급 기능(바인딩, 애니메이션, 스타일)은 DependencyProperty에 의존합니다.
반면 Avalonia에서는 성능과 유연성을 위해 속성을 두 가지로 분류했습니다: StyledProperty(WPF와 유사)와 DirectProperty(더 가볍고 효율적).
1. 주요 클래스 관계
이해를 돕기 위해 각 클래스의 관계를 다음과 같이 설명할 수 있습니다:
- AvaloniaProperty: 모든 속성의 추상 기본 클래스.
- StyledProperty: 다양한 기능을 제공하며 스타일 및 리소스 지원, 하지만 약간 더 많은 오버헤드가 필요.
- DirectProperty: 빠르고 경량, 주로 간단한 속성에 사용되며 스타일 오버라이드를 지원하지 않음.
2. StyledProperty: WPF 개발자에게 친숙한 속성
이것은 WPF의 DependencyProperty의 직접적인 대체품입니다. Avalonia의 강력한 스타일 시스템을 완전히 지원합니다.
- 특징: CSS와 유사한 스타일 시트에서 값 상속을 지원하며 우선 순위 정렬이 가능(예: 로컬 값 > 스타일 값 > 기본값).
- 적용 사례: 대부분의 UI 컨트롤에서 사용되는 사용자 정의 속성(예:
Background,FontSize).
public class CustomControl : Control
{
// 1. 정의: AvaloniaProperty.Register를 사용하여 등록
public static readonly StyledProperty<string> DisplayTextProperty =
AvaloniaProperty.Register<CustomControl, string>(
name: "DisplayText",
defaultValue: "Welcome");
// 2. CLR 프로퍼티 래퍼
public string DisplayText
{
get => GetValue(DisplayTextProperty);
set => SetValue(DisplayTextProperty, value);
}
}
3. DirectProperty: 성능 최적화를 위한 새로운 접근
Avalonia만의 특징으로, 내부 딕셔너리 대신 클래스의 프라이빗 필드를 직접 사용합니다.
- 특징:
- 빠름: 일반 C# 속성과 비슷한 읽기/쓰기 속도.
- 효율적: 메모리 사용이 극히 적음.
- 제한점: 스타일 오버라이드 미지원.
.axaml파일의<Style>에서 값을 변경할 수 없음. - 적용 사례: 데이터 바인딩만 필요한 경우, 또는 매우 높은 성능이 요구되는 리스트 항목 속성.
public class CustomControl : Control
{
// 1. 데이터 저장을 위한 프라이빗 필드 정의
private string _filePath = "untitled.txt";
// 2. DirectProperty 정의: AvaloniaProperty.RegisterDirect 사용
public static readonly DirectProperty<CustomControl, string> FilePathProperty =
AvaloniaProperty.RegisterDirect<CustomControl, string>(
nameof(FilePath),
o => o._filePath,
(o, v) => o._filePath = v);
// 3. 프라이빗 필드 직접 조작
public string FilePath
{
get => _filePath;
set => SetAndRaise(FilePathProperty, ref _filePath, value);
}
}
4. 비교 요약
| 기능 | StyledProperty (WPF 유사) | DirectProperty (Avalonia 특징) |
|---|---|---|
| 저장 방식 | 내부 딕셔너리 | 클래스 멤버 필드 |
| 조회 속도 | 느림(우선 순위 계산 필요) | 매우 빠름(직접 필드 접근) |
| 스타일 지원 | 지원(Setter 사용 가능) | 미지원 |
| 기본값 설정 | 등록 시 정의 | 필드 초기화 시 정의 |
| 메모리 사용량 | 약간 높음 | 매우 낮음 |
설계 이유
WPF에서는 많은 객체들이 속성을 가지고 있을 때 메모리와 CPU 부하가 크다는 문제가 있었습니다.
Avalonia의 접근법은 다음과 같습니다:
- 스타일 시트에서 속성이 변경될 필요가 있다면
StyledProperty를 사용. - 데이터 바인딩이나 표시 용도로만 사용한다면
DirectProperty를 사용하여 렌더링 성능을 향상.