티스토리 뷰
모든 C#프로그래머는 C# Property 개념에 익숙합니다. Property는 Get과 Set과 접근자를 포함하고 있습니다. CLR 환경(Common Language Runtime)에서 제공하기 때문에 종종 CLR Property라고 불리기도 합니다.
Xamarin.Forms는 Bindable Property라고 불리는 향상된 Property를 제공합니다.
Bindable Property는
BindableProperty
Class에 의해 캡슐화되고
BindableObject
Class에 의해 지원됩니다.
이 Class들은 서로 관련된 것처럼 보이지만 전혀 다릅니다: BindableProperty는 Property를 정의하는데 사용됩니다;
반면에 BindableObject는 Bindable Property를 정의하는 Class들을 위한
Base Class로서의 역할을 한다는 점에서 object와 유사하다고 볼 수 있습니다.
이 문서에서는 다음 주제를 다룹니다.
Xamarin.Forms 클래스 계층 구조
ClassHierarchy 샘플은 Xamarin.Forms의 Class 계층구조를 보여줍니다.
최상위 Object 바로아래에는 BindableObject가 위치하고 있습니다.
BindableObject 아래에는
Element Class가 위치하고 있으며,
VisualElement는 Element를 상속하고 있습니다.
VisualElement는
Page
View의 부모입니다.
View는
Layout의 부모입니다.
System.Object
└BindableObject
└Element
└VisualElement
└View
│ └...
│ └Layout
│ └...
│ └Layout<T>
│ └...
└Page
└...
BindableObject의 주요한 역할은 Data Binding을 지원하는 것입니다. Data Binding이란 2개의 객체 인스턴스의 Property를 연결하고
같은 값을 가지도록 유지시켜주는 기술을 말합니다. BindableObject는 Style과 DynamicResource Markup Extension도 지원합니다.
Data Binding은 2가지 방법으로 구현가능합니다. 첫번째가 BindableObject를 상속한 Class가 BindableProperty를 통해
Property를 정의하는 경우 Data Binding이 가능합니다. 두번째로 .NET의 INotifyPropertyChange interface를 구현하는 Class의 경우
Data Binding을 지원할 수 있습니다.
BindableObject 하위에 존재하는 Element는 Xamarin.Forms의 UI 객체들이 부모 자식 계층구조를 가질 수 있도록
지원하는 역할을 합니다.
VisualElement는 Xamarin.Forms에서 스크린 화면을 차지하는 비주얼 객체에 필요한 Property를 제공합니다.
현재 VisualElement는 28개의 Property를 제공하는데 크기, 위치, 배경색, IsEnabled, IsVisible와 같은
시각적이고 기능적인 특성을 다룹니다.
View는 Xamarin.Forms에서 버튼, 슬라이더, 텍스트박스 와 같은 모든 시각적 객체를 가리키는 말로 통합니다. 하지만
View의 자식으로는 Layout Class도 존재한다는 것을 알 수 있습니다. View는
VisualElement에서 3개의 Property를 추가하는데 HorizontalOptions, VerticalOptions,
GestureRecognizers와 같은 Page에게 불필요한 Property입니다.
Layout의 자식 Class들은 자식 View을 가질 수 있습니다.
자식 View는 부모인 Layout이 제공하는 영역 내에서 공간을 차지합니다.
Layout을 상속하는 Class는 오직 1개의 View를 자식으로 가지지만,
제네릭 클래스인 Layout<T>는 Children Property를 제공하며
이를 통해 여러 개의 자식 View를 가질 수 있습니다.
BindableObject와 BindableProperty 살펴보기
BindableObject를 상속한 Class들이 제공하는 CLR Property들은 Bindable Property에 의해
지원된다고 명시되어 있습니다. 예를들어 Label Class의
Text Property는
CLR Property입니다. 또한 Label Class는 BindableProperty Type의
TextProperty
ReadOnly Public Static Field도 정의하고 있습니다.
일반적으로 애플리케이션은 Label의 Text Property를 통해 값을 할당하거나 읽을 수 있지만
BinableObject가 정의하고 있는
SetValue 메서드를
Label.TextProperty 매개변수와 함께 호출하여 Text Property에 값을 할당할 수도 있습니다.
마찬가지로
GetValue 메서드를
Label.TextProperty 매개변수와 함께 호출하여 Text Property의 값을 읽을 수 있습니다.
PropertySettings 샘플에서는
이에 관한 예제를 제공합니다.
실제로 Text CLR Property는 내부적으로 BindableObject의 SetValue나 GetValue
메서드를 Label.TextProperty 매개변수와 함께 호출하는 형태로 구현되어 있습니다.
BindableObject와 BindableProperty는 다음과 같은 지원을 제공합니다.
- Property의 기본 값을 제공함
- Property의 값을 저장
- Property 값의 유효성 검사를 위한 장치를 제공
- 단일 Class의 관련된 Property들의 일관성을 유지 관리
- Property의 값이 변경되었을 때 응답을 제공
- Property의 값이 변경되거나 변경된 후에 실행되는 콜백 메서드를 지원
- DataBinding을 지원
- Style을 지원
- DynamicResource를 지원
Bindable Property에 의해 지원되는 Property 값이 변경되면 BindableObject는
PropertyChanged 이벤트를
호출하여 값이 변경된 Property가 무엇인지 알수 있도록 지원합니다.
만약 동일한 값이 할당된다면 PropertyChanged 이벤트는 실행되지 않습니다.
일부 Property는 Bindable Property에 의해 지원되지 않습니다. 예를들어 Xamarin.Forms의 Span과 같은
Class들은 BindableObject를 상속하지 않습니다. BindableObject를 상속한 Class만이
Bindable Property를 지원할 수 있습니다. 왜냐하면 BindableObject가 SetValue와 GetValue
메서드를 정의하고 있기 때문입니다.
Span은 BindableObject를 상속하지 않기 때문에
Span의 Text Property를 포함한 모든 Property는
Bindable Property에 의해 지원되지 않습니다.
이것이 바로 이전 챕터의 DynamicVsStatic 샘플에서
Span의 Text Property에
DynamicResource를 설정했을 때 Exception이 발생한 이유입니다.
DynamicVsStaticCode 샘플은
Element에 의해 정의되어 있는
SetDynamicResource 메서드를
이용하여 Dynamic Resource를 설정하는 예제를 제공합니다. SetDynamicResource 메서드의 첫번째 매개변수는 BindableProperty Type 객체입니다.
마찬가지로 BindableObject가 정의하고 있는
SetBinding 메서드의 첫번째 매개변수도
BindableProperty 입니다.
Bindable Property 정의
BindableProperty.Create static 메서드를
사용하여 BindableProperty Type의 Static ReadOnly Field를 정의할 수 있으며, 이를 통해 필요한
BindableProperty Property를 직접 정의할 수 있습니다.
Xamarin.FormsBook.Toolkit 라이브러리의
AltLabel Class를 통해
Bindable Property를 정의하는 샘플을 보실 수 있습니다.
이 Class는 Label을 상속하고 있으며 폰트 크기를 Point 단위로 설정 할 수 있는
Bindable Property를 제공합니다. 이에 관한 예제는
PointSizedText 샘플에서
제공하고 있습니다.
BindableProperty.Create 메서드는 4개의 매개변수를 요구합니다.
propertyName: Property의 이름 (CLR Property의 이름과 동일한 문자열로 지정해야 합니다)returnType: CLR Property의 TypedeclaringType: 이 Property를 제공하는 Class의 TypedefaultValue: Property의 기본 값
defaultValue는 object Type으로 전달받기 떄문에
컴파일 타임에 Type이 적절한지 파악하지 못합니다. 따라서 반드시 Type에 맞는 값을 지정하도록 유의해야 합니다.
예를들어 returnType이 double이면 defaultValue는 반드시 0이 아니라
0.0과 같이 double 값을 지정해야 하며, 이를 준수하지 않을 경우 실행 중에 Exception이 발생하게 됩니다.
propertyChanged는 Bindable Property를 정의할 때 자주 사용하는 매개변수 입니다.
-
propertyChanged: Property의 값이 변경되 었을 때 호출되는 Static 메서드로서 값이 변경된 Class의 인스턴스가 첫번째 매개변수로 전달됨
BindableProperty.Create 메서드에서 자주 사용되지 않는 매개변수입니다.
-
defaultBindingMode: Data Binding과 관련하여 사용됩니다. (자세한 내용은 Chapter 16 DataBinding에서 다룹니다.) validateValue: 데이터 유효성 검증을 위한 콜백 메서드propertyChanging: Property의 값이 변경되었을 때 호출되는 콜백 메서드coerceValue: 값을 지정할 때 특정 값으로 강제하기 위한 콜백 메서드defaultValueCreate: Class 인스턴스간에 공유되지 않는 기본값을 생성하기 위한 콜백 메서드 (예: Collection)
ReadOnly Bindable Property
Bindable Property는 ReadOnly가 될 수 있습니다. ReadOnly Bindable Property를 생성하려면
BindableProperty.CreateReadOnly
Static 메서드의 호출을 필요로 하며, 이 메서드 호출을 통해
BindablePropertyKey Type의
Private Static ReadOnly Field를 정의해야합니다.
그런 다음 CLR Property를 정의하고 set 접근자를 private로 구현해야 합니다.
set 접근자에서는
BindablePropertyKey 값을 매개변수로
SetValue 메서드를 호출해야 합니다.
이러한 구현을 통해 Class의 외부에서 Property의 값 변경을 막을 수 있습니다.
BaskervillesCount 샘플에서
CountedLabel Class는
이러한 ReadOnly Bindable Property 구현방법을 보여주고 있습니다.
관련 링크
'Xamarin.Forms Book > 요약' 카테고리의 다른 글
| 10장 요약. XAML Markup Extension (0) | 2018.08.18 |
|---|---|
| 9장 요약. 플랫폼별 API 호출 (0) | 2018.08.18 |
| 8장 요약. 코드와 XAML의 조화 (0) | 2018.08.18 |
| 7장 요약. XAML 및 코드 (0) | 2018.08.15 |
| 6장 요약. 버튼 클릭 (0) | 2018.08.15 |
| 5장 요약. 크기 처리 (0) | 2018.08.12 |
| 4장 요약. 스택 스크롤 (0) | 2018.08.12 |
| 3장 요약. 텍스트 자세히 알아보기 (0) | 2018.08.11 |
- Xamarin.iOS
- ios
- windows
- WPF
- Xamarin.Forms 요약
- TypeScript
- Xamarin.Forms eBook
- MS SQL
- .NET Standard
- Android
- Xamarin
- Xamarin.Forms
- npm
- ASP.NET Core
- material-ui
- VisualStudio
- React
- linux
- flutter
- Vue
- Total
- Today
- Yesterday