티스토리 뷰
모든 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 |
- MS SQL
- flutter
- ios
- React
- .NET Standard
- c#
- WPF
- material-ui
- Xamarin.Forms
- Vue
- VisualStudio
- Xamarin.Forms 요약
- Xamarin
- Xamarin.iOS
- StringComparison
- ASP.NET Core
- TypeScript
- npm
- Xamarin.Forms eBook
- Android
- Total
- Today
- Yesterday