다음을 통해 공유


요약 - 11장. 바인딩할 수 있는 인프라

참고 항목

이 책은 2016년 봄에 출간되었으며, 그 후로 업데이트되지 않았습니다. 이 책의 많은 내용이 지금까지도 무척 유용하나, 일부 내용은 오래되었고 올바르지 않거나 완전하지 않은 주제도 있습니다.

모든 C# 프로그래머는 C# 속성에 익숙합니다. 속성에는 set 접근자 및/또는 get 접근자가 포함됩니다. 종종 이를 공용 언어 런타임에 대한 CLR 속성이라고도 부릅니다.

Xamarin.Forms는 클래스에 의해 BindableProperty 캡슐화되고 클래스에서 지원하는 BindableObject 바인딩 가능한 속성이라는 향상된 속성 정의를 정의합니다. 이러한 클래스는 관련이 있지만 매우 다릅니다. BindableProperty 속성 자체를 BindableObject object 정의하는 데 사용됩니다. 바인딩 가능한 속성을 정의하는 클래스의 기본 클래스라는 것입니다.

Xamarin.Forms 클래스 계층 구조

ClassHierarchy 샘플은 리플렉션을 사용해서 Xamarin.Forms의 클래스 계층 구조를 표시하고 이 계층 구조에서 BindableObject가 수행하는 중요한 역할을 보여 줍니다. BindableObjectObject에서 파생되며 VisualElement가 파생되는 Element에 대한 부모 클래스입니다. 이 클래스는 Layout의 부모 클래스인 PageView의 부모 클래스입니다.

클래스 계층 구조 공유에 대한 세 가지 스크린샷

BindableObject 및 BindableProperty 살펴보기

BindableObject에서 파생되는 클래스에서 많은 CLR 속성은 바인딩할 수 있는 속성으로 "지원된다"고 말합니다. 예를 들어 Label 클래스의 Text 속성은 CLR 속성이지만 Label 클래스도 BindableProperty 형식의 TextProperty라는 공용 정적 읽기 전용 필드를 정의합니다.

애플리케이션은 일반적으로 LabelText 속성을 설정하거나 가져올 수 있습니다. 또는 애플리케이션이 Label.TextProperty 인수로 BindableObject에 의해 정의된 SetValue 메서드를 호출하여 Text를 설정할 수 있습니다. 마찬가지로 애플리케이션은 다시 Label.TextProperty 인수로 GetValue 메서드를 호출하여 Text 속성의 값을 가져올 수 있습니다. 이에 대해서는 PropertySettings 샘플을 참조하십시오.

실제로 Text CLR 속성은 전적으로 Label.TextProperty 정적 속성과 함께 BindableObject에 의해 정의된 SetValueGetValue 메서드를 사용하여 구현됩니다.

BindableObjectBindableProperty는 다음에 대한 지원을 제공합니다.

  • 속성 기본값 제공
  • 현재 값 저장
  • 속성 값 유효성 검사를 위한 메커니즘 제공
  • 단일 클래스에서 관련된 속성 간 일관성 유지 관리
  • 속성 변경에 응답
  • 속성이 변경될 예정이거나 변경된 경우 알림 트리거
  • 데이터 바인딩 지원
  • 스타일 지원
  • 동적 리소스 지원

바인딩할 수 있는 속성으로 지원되는 속성이 변경될 때마다 BindableObject는 변경된 속성을 식별하는 PropertyChanged 이벤트를 발생시킵니다. 속성이 동일한 값으로 설정되었을 때는 이 이벤트가 발생되지 않습니다.

일부 속성은 바인딩 가능한 속성에 의해 지원되지 않으며 일부 Xamarin.Forms 클래스(예: Span )는 파생 BindableObject되지 않습니다. BindableObjectSetValueGetValue 메서드를 정의하기 때문에 BindableObject에서 파생되는 클래스만 바인딩할 수 있는 속성을 지원할 수 있습니다.

Span 파생BindableObject되지 않으므로 바인딩 가능한 속성에 의해 지원되는 속성(예: Text 해당 속성)이 없습니다. 따라서 SpanText 속성에 DynamicResource를 설정하면 이전 장의 DynamicVsStatic 샘플에서 예외가 발생합니다. DynamicVsStaticCode 샘플은 Element로 정의된 SetDynamicResource 메서드를 사용하여 코드에서 동적 리소스를 설정하는 방법을 보여줍니다. 첫 번째 인수는 BindableProperty 형식의 객체입니다.

마찬가지로 BindableObject로 정의된 SetBinding 메서드에는 BindableProperty 형식의 첫 번째 인수가 포함됩니다.

바인딩할 수 있는 속성 정의

BindableProperty 형식의 정적 읽기 전용 필드를 만들도록 정적 BindableProperty.Create 메서드를 사용하여 사용자 고유의 바인딩할 수 있는 속성을 정의할 수 있습니다.

이에 대해서는 Xamarin.FormsBook.Toolkit 라이브러리의 AltLabel 클래스에 나와 있습니다. 클래스가 Label에서 파생되며, 이를 이용해서 글꼴 크기(포인트)를 지정할 수 있습니다. 이에 대해서는 PointSizedText 샘플을 참조하십시오.

BindableProperty.Create 메서드의 네 가지 인수가 필요합니다.

  • propertyName: 속성의 텍스트 이름(CLR 속성 이름과 동일)
  • returnType: CLR 속성의 형식
  • declaringType: 속성을 선언하는 클래스의 형식
  • defaultValue: 속성의 기본값

defaultValueobject 형식이기 때문에 컴파일러가 기본값의 형식을 확인할 수 있어야 합니다. 예를 들어 returnTypedouble이면 defaultValue를 단지 0이 아닌 0.0과 같은 값으로 설정해야 합니다. 그렇지 않으면 형식 불일치로 인해 런타임에 예외가 트리거됩니다.

또한 바인딩할 수 있는 속성에 대해 다음을 포함하는 것이 매우 일반적입니다.

  • propertyChanged: 속성이 값을 변경할 때 호출되는 정적 메서드입니다. 첫 번째 인수는 해당 속성이 변경된 클래스의 인스턴스입니다.

BindableProperty.Create의 다른 인수는 그렇게 일반적이지 않습니다.

  • defaultBindingMode: 데이터 바인딩과 관련하여 사용됩니다(16장에서 설명한 대로). 데이터 바인딩)
  • validateValue: 유효한 값을 확인하기 위한 콜백입니다.
  • propertyChanging: 속성이 변경될 시간을 나타내기 위한 콜백입니다.
  • coerceValue: 설정 값을 다른 값으로 강제 변환하기 위한 콜백입니다.
  • defaultValueCreate: 클래스의 인스턴스 간에 공유될 수 없는 기본값을 만들기 위한 콜백입니다(예: 컬렉션).

읽기 전용 바인딩할 수 있는 속성

바인딩할 수 있는 속성은 읽기 전용일 수 있습니다. 읽기 전용 바인딩할 수 있는 속성을 만들려면 정적 메서드 BindableProperty.CreateReadOnly를 호출하여 BindablePropertyKey 형식의 프라이빗 정적 읽기 전용 필드를 정의해야 합니다.

그런 다음, CLR 속성 set 접근자를 private로 정의하여 BindablePropertyKey 개체로 SetValue 오버로드를 호출합니다. 그러면 속성이 클래스 외부에 설정되지 않도록 방지됩니다.

이에 대해서는 BaskervillesCount 샘플에 사용되는 CountedLabel 클래스를 참조하십시오.