다음을 통해 공유


Xamarin.Forms 기본 바인딩

Xamarin.Forms 데이터 바인딩은 두 개의 개체 사이의 속성 쌍을 연결하며, 이러한 개체 중 적어도 하나는 일반적으로 사용자 인터페이스 개체입니다. 이러한 두 개체는 대상원본이라고 합니다.

  • 대상은 데이터 바인딩이 설정된 개체(및 속성)입니다.
  • 원본은 데이터 바인딩에서 참조하는 개체(및 속성)입니다.

이 구분은 경우에 따라 다소 혼란스러울 수 있습니다. 가장 간단한 경우 데이터는 원본에서 대상으로 이동합니다. 즉 대상 속성의 값이 원본 속성의 값에서 설정됩니다. 하지만 어떤 경우에는 데이터가 대상에서 원본으로 또는 양방향으로 이동할 수 있습니다. 혼란을 방지하기 위해 데이터를 받는 것이 아니라 데이터를 제공하는 경우에도 대상이 항상 데이터 바인딩이 설정된 개체라는 점을 명심하세요.

바인딩 컨텍스트가 있는 바인딩

데이터 바인딩은 일반적으로 XAML에 완전히 지정되지만 코드에서 데이터 바인딩을 확인하는 것이 좋습니다. 기본 코드 바인딩 페이지에는 LabelSlider가 있는 XAML 파일이 포함됩니다.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicCodeBindingPage"
             Title="Basic Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="48"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

Slider는 0 - 360의 범위로 설정됩니다. 이 프로그램의 목적은 Slider를 조작하여 Label을 회전시키는 것입니다.

데이터 바인딩이 없으면 SliderValueChanged 이벤트를 SliderValue 속성에 액세스하고 해당 값을 LabelRotation 속성으로 설정하는 이벤트 처리기로 설정합니다. 데이터 바인딩은 이 작업을 자동화하므로 이벤트 처리기와 그 안에 있는 코드가 더 이상 필요하지 않습니다.

Element, VisualElement, ViewView 파생문이 포함된 BindableObject에서 파생되는 모든 클래스의 인스턴스에 바인딩을 설정할 수 있습니다. 바인딩은 항상 대상 개체에 설정됩니다. 바인딩은 원본 개체를 참조합니다. 데이터 바인딩을 설정하려면 대상 클래스의 다음 두 멤버를 사용합니다.

  • BindingContext 속성은 원본 개체를 지정합니다.
  • SetBinding 메서드는 대상 속성 및 원본 속성을 지정합니다.

이 예제에서 Label은 바인딩 대상이고 Slider는 바인딩 원본입니다. Slider 원본의 변경은 Label 대상의 회전에 영향을 줍니다. 데이터는 원본에서 대상으로 이동합니다.

BindableObject에서 정의된 SetBinding 메서드에 Binding 클래스에서 파생되는 BindingBase 형식의 인수가 있지만, BindableObjectExtensions 클래스에서 정의된 다른 SetBinding 메서드가 있습니다. 기본 코드 바인딩 샘플의 코드 숨김 파일은 이 클래스의 더 간단한 SetBinding 확장 메서드를 사용합니다.

public partial class BasicCodeBindingPage : ContentPage
{
    public BasicCodeBindingPage()
    {
        InitializeComponent();

        label.BindingContext = slider;
        label.SetBinding(Label.RotationProperty, "Value");
    }
}

Label 개체는 바인딩 대상이므로 이 속성이 설정되고 메서드가 호출되는 개체입니다. BindingContext 속성은 바인딩 원본, 즉 Slider를 나타냅니다.

SetBinding 메서드는 바인딩 대상에서 호출되지만 대상 속성과 원본 속성을 모두 지정합니다. 대상 속성은 BindableProperty 개체, 즉 Label.RotationProperty로 지정됩니다. 원본 속성은 문자열로 지정되고 SliderValue 속성을 나타냅니다.

SetBinding 메서드는 데이터 바인딩의 가장 중요한 규칙 중 하나를 표시합니다.

대상 속성은 바인딩 가능한 속성으로 지원되어야 합니다.

이 규칙은 대상 개체가 BindableObject에서 파생되는 클래스의 인스턴스여야 함을 암시합니다. 바인딩 가능한 개체 및 속성에 대한 개요는 바인딩 가능한 속성 문서를 참조하세요.

문자열로 지정된 원본 속성에 대해 이러한 규칙은 없습니다. 내부적으로 리플렉션은 실제 속성에 액세스하는 데 사용됩니다. 그러나 이 특별한 경우에는 Value 속성도 바인딩 가능한 속성으로 지원됩니다.

코드는 다소 간소화될 수 있습니다. 즉 RotationProperty 바인딩 가능한 속성은 VisualElement에서 정의되고 LabelContentPage에도 상속되므로 SetBinding 호출에서 클래스 이름이 필요하지 않습니다.

label.SetBinding(RotationProperty, "Value");

그러나 클래스 이름이 포함되면 대상 개체를 알리는 데 도움이 됩니다.

Slider를 조작하면 이에 따라 Label이 회전합니다.

기본 코드 바인딩

기본 Xaml 바인딩 페이지는 XAML에서 전체 데이터 바인딩을 정의한다는 점을 제외하고는 기본 코드 바인딩과 동일합니다.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicXamlBindingPage"
             Title="Basic XAML Binding">
    <StackLayout Padding="10, 0">
        <Label Text="TEXT"
               FontSize="80"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand"
               BindingContext="{x:Reference Name=slider}"
               Rotation="{Binding Path=Value}" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

코드에서와 마찬가지로 데이터 바인딩은 대상 개체, 즉 Label에 설정됩니다. 두 개의 XAML 태그 확장이 포함됩니다. 이러한 확장은 중괄호 구분 기호로 즉시 인식할 수 있습니다.

  • x:Reference 태그 확장은 원본 개체, 즉 slider라는 Slider를 참조하는 데 필요합니다.
  • Binding 태그 확장에서 LabelRotation 속성을 SliderValue 속성에 연결합니다.

XAML 태그 확장에 대한 자세한 내용은 XAML 태그 확장 문서를 참조하세요. x:Reference 태그 확장은 ReferenceExtension 클래스에서 지원되고, BindingBindingExtension 클래스에서 지원됩니다. XML 네임스페이스 접두사가 표시되면 x:Reference는 XAML 2009 사양의 일부이지만 Binding은 Xamarin.Forms의 일부입니다. 따옴표는 중괄호 안에 표시되지 않습니다.

BindingContext를 설정할 때 x:Reference 태그 확장을 잊어버리기 쉽습니다. 다음과 같이 실수로 속성을 바인딩 원본 이름으로 직접 설정하는 것이 일반적입니다.

BindingContext="slider"

하지만 이는 올바르지 않습니다. 해당 태그는 BindingContext 속성을 "slider" 문자로 철자되는 string 개체로 설정합니다!

원본 속성은 Binding 클래스의 Path 속성에 해당하는 BindingExtensionPath 속성으로 지정됩니다.

기본 XAML 바인딩 페이지에 표시된 태그는 간소화할 수 있습니다. 즉 x:ReferenceBinding과 같은 XAML 태그 확장에는 콘텐츠 속성 특성이 정의될 수 있으며, 이는 XAML 태그 확장의 경우 속성 이름을 표시할 필요가 없음을 의미합니다. Name 속성은 x:Reference의 콘텐츠 속성이고, Path 속성은 Binding의 콘텐츠 속성입니다. 즉 다음 식에서 해당 속성을 제외할 수 있습니다.

<Label Text="TEXT"
       FontSize="80"
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand"
       BindingContext="{x:Reference slider}"
       Rotation="{Binding Value}" />

바인딩 컨텍스트가 없는 바인딩

BindingContext 속성은 데이터 바인딩의 중요한 구성 요소이지만 항상 필요한 것은 아닙니다. 대신 원본 개체를 SetBinding 호출 또는 Binding 태그 확장에 지정할 수 있습니다.

이는 대체 코드 바인딩 샘플에 나와 있습니다. XAML 파일은 SliderLabelScale 속성을 제어하도록 정의된다는 점을 제외하고는 기본 코드 바인딩 샘플과 비슷합니다. 이러한 이유로 Slider –2에서 2까지의 범위로 설정됩니다.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeCodeBindingPage"
             Title="Alternative Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

코드 숨김 파일은 BindableObject에서 정의된 SetBinding 메서드를 사용하여 바인딩을 설정합니다. 인수는 Binding 클래스에 대한 생성자입니다.

public partial class AlternativeCodeBindingPage : ContentPage
{
    public AlternativeCodeBindingPage()
    {
        InitializeComponent();

        label.SetBinding(Label.ScaleProperty, new Binding("Value", source: slider));
    }
}

Binding 생성자에는 6개의 매개 변수가 있으므로 source 매개 변수는 명명된 인수로 지정됩니다. 인수는 slider 개체입니다.

이 프로그램을 실행하면 약간 놀랄 수도 있습니다.

대체 코드 바인딩

왼쪽의 iOS 화면에서는 페이지가 처음 나타날 때 화면이 표시되는 모양을 보여 줍니다. Label은 어디에 있을까요?

문제는 Slider의 초기 값이 0이라는 것입니다. 이로 인해 LabelScale 속성도 0으로 설정되어 기본값인 1을 재정의합니다. 따라서 초기에는 Label이 표시되지 않습니다. Android 스크린샷에서 보여 주듯이 Slider을(를) 조작하여 Label이(가) 다시 나타나도록 할 수 있지만, 초기에 표시되지 않으면 당황스러울 수 있습니다.

다음 문서에서 Scale 속성의 기본값에서 Slider를 초기화하여 이 문제를 방지하는 방법을 알아봅니다.

참고 항목

또한 VisualElement 클래스는 VisualElement의 크기를 가로 및 세로 방향으로 다르게 확장할 수 있는 ScaleXScaleY 속성을 정의합니다.

대체 XAML 바인딩 페이지에는 XAML에서 완전히 동일한 바인딩이 표시됩니다.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeXamlBindingPage"
             Title="Alternative XAML Binding">
    <StackLayout Padding="10, 0">
        <Label Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand"
               Scale="{Binding Source={x:Reference slider},
                               Path=Value}" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

이제 Binding 태그 확장에는 쉼표로 구분된 두 개의 속성 세트인 SourcePath가 있습니다. 원하는 경우 동일한 줄에 나타날 수 있습니다.

Scale="{Binding Source={x:Reference slider}, Path=Value}" />

Source 속성은 포함된 x:Reference 태그 확장으로 설정되며, 그렇지 않으면 BindingContext를 설정하는 것과 동일한 구문이 포함됩니다. 중괄호 안에 따옴표가 표시되지 않으며, 두 속성은 쉼표로 구분해야 합니다.

Binding 태그 확장의 콘텐츠 속성은 Path이지만, 태그 확장의 Path= 부분은 식의 첫 번째 속성인 경우에만 제거할 수 있습니다. Path= 부분을 제거하려면 다음 두 속성을 교환해야 합니다.

Scale="{Binding Value, Source={x:Reference slider}}" />

XAML 태그 확장은 일반적으로 중괄호로 구분되지만, 개체 요소로도 표현할 수 있습니다.

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand">
    <Label.Scale>
        <Binding Source="{x:Reference slider}"
                 Path="Value" />
    </Label.Scale>
</Label>

이제 SourcePath 속성은 일반 XAML 특성입니다. 값이 따옴표 안에 표시되고, 특성은 쉼표로 구분되지 않습니다. 또한 x:Reference 태그 확장은 개체 요소가 될 수 있습니다.

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand">
    <Label.Scale>
        <Binding Path="Value">
            <Binding.Source>
                <x:Reference Name="slider" />
            </Binding.Source>
        </Binding>
    </Label.Scale>
</Label>

이 구문은 일반적이지 않지만, 때때로 복잡한 개체가 관련되는 경우에는 필요합니다.

지금까지 표시된 예제에서는 BindingContext 속성과 BindingSource 속성을 x:Reference 태그 확장으로 설정하여 페이지의 다른 보기를 참조했습니다. 이 두 속성은 Object 형식이며, 바인딩 원본에 적합한 속성이 포함된 개체로 설정할 수 있습니다.

앞서의 문서에서 BindingContext 또는 Source 속성은 정적 속성 또는 필드의 값을 참조하는 x:Static 태그 확장, 리소스 사전에 저장된 개체를 참조하는 StaticResource 태그 확장으로 설정하거나, 일반적으로(항상은 아님) ViewModel의 인스턴스인 개체로 직접 설정할 수 있음을 알 수 있습니다.

또한 BindingContext 속성을 Binding 개체로 설정하여 BindingSourcePath 속성에서 바인딩 컨텍스트를 정의할 수도 있습니다.

바인딩 컨텍스트 상속

이 문서에서는 BindingContext 속성 또는 Binding 개체의 Source 속성을 사용하여 원본 개체를 지정할 수 있음을 살펴보았습니다. 둘 다 설정되는 경우 BindingSource 속성이 BindingContext보다 우선합니다.

BindingContext 속성에는 다음과 같은 매우 중요한 특징이 있습니다.

BindingContext 속성의 설정은 시각적 트리를 통해 상속됩니다.

여기서 볼 수 있듯이 바인딩 식을 간소화하는 데 매우 유용할 수 있으며, 경우에 따라 특히 MVVM(Model-View-ViewModel) 시나리오에서 매우 유용합니다.

바인딩 컨텍스트 상속 샘플은 바인딩 컨텍스트의 상속에 대한 간단한 데모입니다.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BindingContextInheritancePage"
             Title="BindingContext Inheritance">
    <StackLayout Padding="10">

        <StackLayout VerticalOptions="FillAndExpand"
                     BindingContext="{x:Reference slider}">

            <Label Text="TEXT"
                   FontSize="80"
                   HorizontalOptions="Center"
                   VerticalOptions="EndAndExpand"
                   Rotation="{Binding Value}" />

            <BoxView Color="#800000FF"
                     WidthRequest="180"
                     HeightRequest="40"
                     HorizontalOptions="Center"
                     VerticalOptions="StartAndExpand"
                     Rotation="{Binding Value}" />
        </StackLayout>

        <Slider x:Name="slider"
                Maximum="360" />

    </StackLayout>
</ContentPage>

StackLayoutBindingContext 속성은 slider 개체로 설정됩니다. 이 바인딩 컨텍스트는 LabelBoxView 모두에서 상속되며, 둘 모두의 Rotation 속성이 SliderValue 속성으로 설정됩니다.

바인딩 컨텍스트 상속

다음 문서에서는 바인딩 모드에서 대상 개체와 원본 개체 간의 데이터 흐름을 변경하는 방법을 보여 줍니다.

Channel 9YouTube에서 더 많은 Xamarin 비디오를 확인하세요.