4부.Part 4. 데이터 바인딩 기본 사항Data Binding Basics

샘플 다운로드 샘플 다운로드Download Sample Download the sample

데이터 바인딩 변경 하나에 다른 변경으로 인해 있도록 연결할 두 개체의 속성을 허용 합니다. 매우 유용한 도구이며 데이터 바인딩은 코드로만 정의할 수 있는 반면 XAML은 바로 가기 및 편의성을 제공합니다. 따라서 Xamarin.Forms에서 태그 확장 중 가장 중요한 하나는 바인딩(Binding)입니다.Data bindings allow properties of two objects to be linked so that a change in one causes a change in the other. This is a very valuable tool, and while data bindings can be defined entirely in code, XAML provides shortcuts and convenience. Consequently, one of the most important markup extensions in Xamarin.Forms is Binding.

데이터 바인딩Data Bindings

데이터 바인딩은 두 개체의 속성을 연결하고, sourcetarget을 호출합니다.Data bindings connect properties of two objects, called the source and the target. 코드에서 두 단계가 필요 합니다. BindingContext 원본 개체를 대상 개체의 속성을 설정 해야 하며 SetBinding 메서드 (종종 함께 사용를 Binding 클래스) 원본의 속성에 해당 개체의 속성 바인딩 대상 개체에서 호출 해야 개체입니다.In code, two steps are required: The BindingContext property of the target object must be set to the source object, and the SetBinding method (often used in conjunction with the Binding class) must be called on the target object to bind a property of that object to a property of the source object.

대상 속성은 대상 개체가 BindableObject에서 파생되어야 한다는 것을 의미하는 바인딩 가능한 속성이어야 합니다.The target property must be a bindable property, which means that the target object must derive from BindableObject. 온라인 Xamarin.Forms 문서는 어떤 속성이 바인딩 가능한 속성인지를 나타냅니다.The online Xamarin.Forms documentation indicates which properties are bindable properties. Text와 같은 Label의 속성은 바인딩 가능한 속성 TextProperty와 연관됩니다.A property of Label such as Text is associated with the bindable property TextProperty.

태그에서도 Binding 태그 확장이 SetBinding 호출과 Binding 클래스를 대신한다는 점을 제외하면 코드에서 필요한 것과 동일한 두 단계를 수행해야 합니다.In markup, you must also perform the same two steps that are required in code, except that the Binding markup extension takes the place of the SetBinding call and the Binding class.

그러나 XAML에서 데이터 바인딩을 정의할 때 대상 개체의 BindingContext를 설정하는 여러 가지 방법이 있습니다.However, when you define data bindings in XAML, there are multiple ways to set the BindingContext of the target object. 때로는 StaticResourcex:Static 태그 확장을 사용하여, 때로는 BindingContext 속성 요소 태그의 내용으로 코드 비하인드에서 설정됩니다.Sometimes it’s set from the code-behind file, sometimes using a StaticResource or x:Static markup extension, and sometimes as the content of BindingContext property-element tags.

바인딩 가장 자주 사용 되는 MVVM (Model View ViewModel) 응용 프로그램 아키텍처의 인식에서 일반적으로 기본 데이터 모델을 사용 하 여 프로그램의 시각적 개체를 연결할에 설명 된 대로 5 부입니다. 데이터 바인딩부터 MVVM, 하지만 다른 시나리오가 가능 합니다.Bindings are used most often to connect the visuals of a program with an underlying data model, usually in a realization of the MVVM (Model-View-ViewModel) application architecture, as discussed in Part 5. From Data Bindings to MVVM, but other scenarios are possible.

뷰를 뷰에 바인딩View-to-View Bindings

같은 페이지에서 두 가지 뷰 속성을 연결하기 위한 데이터 바인딩을 정의할 수 있습니다.You can define data bindings to link properties of two views on the same page. 이 경우 x:Reference 태그 확장을 사용하여 대상 개체의 BindingContext를 설정합니다.In this case, you set the BindingContext of the target object using the x:Reference markup extension.

다음은 Slider와 두 개의 Label 뷰를 포함하는 XAML 파일입니다. 다음과 같이 레이블 중 하나는 Slider 값에 의해 회전되고, 다른 하나는 Slider 값을 표시합니다.Here’s a XAML file that contains a Slider and two Label views, one of which is rotated by the Slider value and another which displays the Slider value:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.SliderBindingsPage"
             Title="Slider Bindings Page">

    <StackLayout>
        <Label Text="ROTATION"
               BindingContext="{x:Reference Name=slider}"
               Rotation="{Binding Path=Value}"
               FontAttributes="Bold"
               FontSize="Large"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

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

        <Label BindingContext="{x:Reference slider}"
               Text="{Binding Value, StringFormat='The angle is {0:F0} degrees'}"
               FontAttributes="Bold"
               FontSize="Large"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

Sliderx:Reference 태그 확장을 사용하여 두 개의 Label 뷰에 의해 참조되는 x:Name 특성을 포함하고 있습니다.The Slider contains an x:Name attribute that is referenced by the two Label views using the x:Reference markup extension.

x:Reference 바인딩 확장은 참조된 요소의 이름으로 설정하기 위해 Name이라는 속성을 정의하는데, 이 경우에는 slider입니다.The x:Reference binding extension defines a property named Name to set to the name of the referenced element, in this case slider. 그러나 x:Reference 태그 확장을 정의하는 ReferenceExtension 클래스는 또한 명시적으로 필수가 아닌 Name을 위한 ContentProperty 특성을 정의합니다.However, the ReferenceExtension class that defines the x:Reference markup extension also defines a ContentProperty attribute for Name, which means that it isn’t explicitly required. 다양성을 위해서, 다음과 같이 x:Reference는 "Name="을 포함하지만 두 번째는 포함하지 않습니다.Just for variety, the first x:Reference includes “Name=” but the second does not:

BindingContext="{x:Reference Name=slider}"
…
BindingContext="{x:Reference slider}"

Binding 태그 확장 자체는 BindingBaseBinding 클래스처럼 여러 속성을 가질 수 있습니다.The Binding markup extension itself can have several properties, just like the BindingBase and Binding class. Binding에 대한 ContentPropertyPath이지만, 태그 확장의 일부인 "Path="은 경로가 Binding 태그 확장에서 첫 번째 항목인 경우 생략할 수 있습니다.The ContentProperty for Binding is Path, but the “Path=” part of the markup extension can be omitted if the path is the first item in the Binding markup extension. 다음과 같이 첫 번째 예제는 "Path="이 있지만 두 번째 예제에서는 생략합니다.The first example has “Path=” but the second example omits it:

Rotation="{Binding Path=Value}"
…
Text="{Binding Value, StringFormat='The angle is {0:F0} degrees'}"

다음과 같이 속성은 모두 한줄에 표현하거나 여러 줄로 구분할 수 있습니다.The properties can all be on one line or separated into multiple lines:

Text="{Binding Value,
               StringFormat='The angle is {0:F0} degrees'}"

무엇이든 편리한 것을 수행하면 됩니다.Do whatever is convenient.

Binding 태그 확장에서 두 번째 StringFormat 속성을 확인하십시오.Notice the StringFormat property in the second Binding markup extension. Xamarin.Forms에 바인딩은 모든 암시적 유형 변환을 수행하지 않으므로 문자열이 아닌 개체를 문자열로 표시해야 하는 경우 유형 변환기를 제공하거나 StringFormat을 사용해야 합니다.In Xamarin.Forms, bindings do not perform any implicit type conversions, and if you need to display a non-string object as a string you must provide a type converter or use StringFormat. 배후에서 정적(static) String.Format 메서드가 StringFormat을 구현하는 데 사용됩니다.Behind the scenes, the static String.Format method is used to implement StringFormat. .NET 서식 지정 사양에는 중괄호가 포함되어 있기 때문에 잠제적으로 문제가 될 수 있습니다.That’s potentially a problem, because .NET formatting specifications involve curly braces, which are also used to delimit markup extensions. 이로 인해 XAML 파서가 혼동될 위험이 생깁니다.This creates a risk of confusing the XAML parser. 해당 문제를 방지하려면 작은따옴표로 전체 서식 문자열을 묶습니다.To avoid that, put the entire formatting string in single quotation marks:

Text="{Binding Value, StringFormat='The angle is {0:F0} degrees'}"

실행 프로그램은 다음과 같습니다.Here’s the running program:

바인딩 모드The Binding Mode

단일 뷰는 여러 속성에 데이터 바인딩을 가질 수 있습니다.A single view can have data bindings on several of its properties. 그러나 각 뷰는 단 하나의 BindingContext만 가질 수 있기 때문에 해당 뷰에 다수의 데이터를 바인딩하려면 동일한 개체의 모든 속성을 참조해야 합니다.However, each view can have only one BindingContext, so multiple data bindings on that view must all reference properties of the same object.

해당 문제와 기타 문제에 대한 해결책은 다음과 같이 BindingMode 열거형의 멤버로 설정된 Mode의 속성과 관련됩니다.The solution to this and other problems involves the Mode property, which is set to a member of the BindingMode enumeration:

  • Default
  • OneWay -값이 원본(source)에서 대상(target)으로 전송됩니다.OneWay — values are transferred from the source to the target
  • OneWayToSource -값이 대상에서 원본으로 전송됩니다.OneWayToSource — values are transferred from the target to the source
  • TwoWay -값이 원본과 대상 간의 값 양방향으로 전송됩니다.TwoWay — values are transferred both ways between source and target
  • OneTime -대상으로 하지만 경우에만 원본에서 데이터 이동은 BindingContext 변경OneTime — data goes from source to target, but only when the BindingContext changes

다음 프로그램은 OneWayToSourceTwoWay 바인딩 모드의 일반적인 사용법을 보여줍니다.The following program demonstrates one common use of the OneWayToSource and TwoWay binding modes. 네 개의 Slider 뷰는 LabelScale, Rotate, RotateXRotateY 속성을 제어하기 위한 것입니다.Four Slider views are intended to control the Scale, Rotate, RotateX, and RotateY properties of a Label. 처음에는 Label의 네 가지 속성이 각각 Slider에 의해 설정되기 때문에 데이터 바인딩 대상이어야 하는 것처럼 보입니다.At first, it seems as if these four properties of the Label should be data-binding targets because each is being set by a Slider. 그러나, LabelBindingContext는 하나의 개체일 수 있으며, 네 개의 다른 슬라이더가 있습니다.However, the BindingContext of Label can be only one object, and there are four different sliders.

따라서 모든 바인딩을 설정 보이는 이전 버전과 방법으로: BindingContext 로 설정 되어 각 네 개의 슬라이더를 Label에 바인딩을 설정 하 고는 Value 슬라이더의 속성입니다.For that reason, all the bindings are set in seemingly backwards ways: The BindingContext of each of the four sliders is set to the Label, and the bindings are set on the Value properties of the sliders. OneWayToSourceTwoWay 모드를 사용하면, 다음과 같이 Value 속성은 LabelScale, Rotate, RotateXRotateY 속성인 원본 속성을 설정할 수 있습니다.By using the OneWayToSource and TwoWay modes, these Value properties can set the source properties, which are the Scale, Rotate, RotateX, and RotateY properties of the Label:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.SliderTransformsPage"
             Padding="5"
             Title="Slider Transforms Page">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>

        <!-- Scaled and rotated Label -->
        <Label x:Name="label"
               Text="TEXT"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <!-- Slider and identifying Label for Scale -->
        <Slider x:Name="scaleSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="1" Grid.Column="0"
                Maximum="10"
                Value="{Binding Scale, Mode=TwoWay}" />

        <Label BindingContext="{x:Reference scaleSlider}"
               Text="{Binding Value, StringFormat='Scale = {0:F1}'}"
               Grid.Row="1" Grid.Column="1"
               VerticalTextAlignment="Center" />

        <!-- Slider and identifying Label for Rotation -->
        <Slider x:Name="rotationSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="2" Grid.Column="0"
                Maximum="360"
                Value="{Binding Rotation, Mode=OneWayToSource}" />

        <Label BindingContext="{x:Reference rotationSlider}"
               Text="{Binding Value, StringFormat='Rotation = {0:F0}'}"
               Grid.Row="2" Grid.Column="1"
               VerticalTextAlignment="Center" />

        <!-- Slider and identifying Label for RotationX -->
        <Slider x:Name="rotationXSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="3" Grid.Column="0"
                Maximum="360"
                Value="{Binding RotationX, Mode=OneWayToSource}" />

        <Label BindingContext="{x:Reference rotationXSlider}"
               Text="{Binding Value, StringFormat='RotationX = {0:F0}'}"
               Grid.Row="3" Grid.Column="1"
               VerticalTextAlignment="Center" />

        <!-- Slider and identifying Label for RotationY -->
        <Slider x:Name="rotationYSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="4" Grid.Column="0"
                Maximum="360"
                Value="{Binding RotationY, Mode=OneWayToSource}" />

        <Label BindingContext="{x:Reference rotationYSlider}"
               Text="{Binding Value, StringFormat='RotationY = {0:F0}'}"
               Grid.Row="4" Grid.Column="1"
               VerticalTextAlignment="Center" />
    </Grid>
</ContentPage>

Slider 뷰 중 3개의 바인딩은 OneWayToSource이며, Slider 값은 label이라는 Label의 해당 BindingContext 속성에 변화를 일으킨다는 것을 의미합니다.The bindings on three of the Slider views are OneWayToSource, meaning that the Slider value causes a change in the property of its BindingContext, which is the Label named label. 해당 세 가지 Slider 뷰는 LabelRotate, RotateXRotateY 속성을 변경시킵니다.These three Slider views cause changes to the Rotate, RotateX, and RotateY properties of the Label.

그러나 Scale 속성에 대한 바인딩은 TwoWay입니다.However, the binding for the Scale property is TwoWay. 이것은 Scale 속성이 기본값 1을 가지며 TwoWay 바인딩을 사용하면 Slider 초기 값이 0이 아닌 1로 설정됩니다.This is because the Scale property has a default value of 1, and using a TwoWay binding causes the Slider initial value to be set at 1 rather than 0. 해당 바인딩이 OneWayToSource라면 Scale 속성은 초기에 Slider 기본값 0으로 설정됩니다.If that binding were OneWayToSource, the Scale property would initially be set to 0 from the Slider default value. Label이 표시되지 않으며, 사용자에게 약간의 혼동이 발생할 수 있습니다.The Label would not be visible, and that might cause some confusion to the user.

참고

VisualElement 클래스는 또한 x축 및 y축 각각 VisualElement로 크기를 조정하는 ScaleX ScaleY 속성을 가지고 있습니다.The VisualElement class also has ScaleX and ScaleY properties, which scale the VisualElement on the x-axis and y-axis respectively.

바인딩 및 컬렉션Bindings and Collections

템플릿 기반 ListView보다 XAML 및 데이터 바인딩의 기능을 잘 보여주는 것은 없습니다.Nothing illustrates the power of XAML and data bindings better than a templated ListView.

ListViewIEnumerable 유형의 ItemsSource 속성을 정의하고, 해당 컬렉션의 항목을 표시합니다.ListView defines an ItemsSource property of type IEnumerable, and it displays the items in that collection. 해당 항목은 모든 유형의 개체가 될 수 있습니다.These items can be objects of any type. 기본적으로 ListView는 각 항목의 ToString 메서드를 사용하여 해당 항목을 표시합니다.By default, ListView uses the ToString method of each item to display that item. 경우에 따라 이것이 바로 원하는 것일 수 있지만 대부분의 경우에 ToString은 개체의 완전한 클래스 이름만을 반환합니다.Sometimes this is just what you want, but in many cases, ToString returns only the fully-qualified class name of the object.

그러나 ListView 컬렉션의 항목은 Cell에서 파생된 클래스를 포함하는 template을 사용하여 원하는 방식으로 표시할 수 있습니다.However, the items in the ListView collection can be displayed any way you want through the use of a template, which involves a class that derives from Cell. 템플릿은 ListView의 모든 항목에 대해 복제되고, 템플릿에서 설정된 데이터 바인딩은 개별 복제본으로 전송됩니다.The template is cloned for every item in the ListView, and data bindings that have been set on the template are transferred to the individual clones.

ViewCell 클래스를 사용하여 해당 항목에 대한 사용자 지정 셀을 생성하는 경우가 많습니다.Very often, you’ll want to create a custom cell for these items using the ViewCell class. 이 프로세스는 코드에서 다소 복잡하지만 XAML에서는 매우 간단합니다.This process is somewhat messy in code, but in XAML it becomes very straightforward.

XamlSamples 프로젝트에는 NamedColor라는 클래스가 포함되어 있습니다.Included in the XamlSamples project is a class called NamedColor. 각각의 NamedColor 개체는 NameFriendlyName 속성이 string 유형이고 Color 속성이 Color 유형입니다.Each NamedColor object has Name and FriendlyName properties of type string, and a Color property of type Color. 또한 NamedColor는 Xamarin.Forms Color 클래스에 정의된 색상에 해당하는 Color 유형의 141개의 정적 읽기 전용 필드를 가지고 있습니다.In addition, NamedColor has 141 static read-only fields of type Color corresponding to the colors defined in the Xamarin.Forms Color class. 정적 생성자는 해당 정적 필드에 대응하는 NamedColor 개체를 포함하는 IEnumerable<NamedColor> 컬렉션을 생성하고 그것을 자신의 공용(public) 정적(static) All 속성에 할당합니다.A static constructor creates an IEnumerable<NamedColor> collection that contains NamedColor objects corresponding to these static fields, and assigns it to its public static All property.

정적 NamedColor.All 속성을 ListViewItemsSource에 설정하는 것은 다음과 같이 x:Static 태그 확장을 사용하면 간단합니다.Setting the static NamedColor.All property to the ItemsSource of a ListView is easy using the x:Static markup extension:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XamlSamples;assembly=XamlSamples"
             x:Class="XamlSamples.ListViewDemoPage"
             Title="ListView Demo Page">

    <ListView ItemsSource="{x:Static local:NamedColor.All}" />

</ContentPage>

다음과 같이 결과 표시는 항목이 실제로 XamlSamples.NamedColor 유형임을 입증하고 있습니다.The resultant display establishes that the items are truly of type XamlSamples.NamedColor:

정보가 많지는 않지만 ListView는 스크롤이 가능하고 선택이 가능합니다.It’s not much information, but the ListView is scrollable and selectable.

항목에 대한 템플릿을 정의하려면 ItemTemplate 속성을 속성 요소로 분리하여 ViewCell을 참조하는 DataTemplate으로 설정합니다.To define a template for the items, you’ll want to break out the ItemTemplate property as a property element, and set it to a DataTemplate, which then references a ViewCell. ViewCellView 속성에 각 항목을 표시하기 위한 하나 이상의 뷰 레이아웃을 정의할 수 있습니다.To the View property of the ViewCell you can define a layout of one or more views to display each item. 다음은 간단한 예 입니다.Here’s a simple example:

<ListView ItemsSource="{x:Static local:NamedColor.All}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <ViewCell.View>
                    <Label Text="{Binding FriendlyName}" />
                </ViewCell.View>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

참고

셀, 셀의 자식에 대 한 바인딩 소스는는 ListView.ItemsSource 컬렉션입니다.The binding source for cells, and children of cells, is the ListView.ItemsSource collection.

Label 요소는 ViewCellView 속성으로 설정됩니다.The Label element is set to the View property of the ViewCell. (ViewCell.View 태그는 View 속성이 ViewCell의 콘텐츠 속성이므로 필요하지 않습니다.) 해당 태그는 다음과 같이 각 NamedColor 개체의 FriendlyName 속성을 표시합니다.(The ViewCell.View tags are not needed because the View property is the content property of ViewCell.) This markup displays the FriendlyName property of each NamedColor object:

훨씬 낫습니다.Much better. 이제 더 많은 정보와 실제 색상으로 항목 템플릿을 멋지게 꾸미기만 하면 됩니다.Now all that’s needed is to spruce up the item template with more information and the actual color. 해당 템플릿을 지원하기 위해 일부 값과 개체가 다음과 같이 페이지의 리소스 사전에 정의되어 있습니다.To support this template, some values and objects have been defined in the page’s resource dictionary:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XamlSamples"
             x:Class="XamlSamples.ListViewDemoPage"
             Title="ListView Demo Page">

    <ContentPage.Resources>
        <ResourceDictionary>
            <OnPlatform x:Key="boxSize"
                        x:TypeArguments="x:Double">
                <On Platform="iOS, Android, UWP" Value="50" />
            </OnPlatform>

            <OnPlatform x:Key="rowHeight"
                        x:TypeArguments="x:Int32">
                <On Platform="iOS, Android, UWP" Value="60" />
            </OnPlatform>

            <local:DoubleToIntConverter x:Key="intConverter" />

        </ResourceDictionary>
    </ContentPage.Resources>

    <ListView ItemsSource="{x:Static local:NamedColor.All}"
              RowHeight="{StaticResource rowHeight}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Padding="5, 5, 0, 5"
                                 Orientation="Horizontal"
                                 Spacing="15">

                        <BoxView WidthRequest="{StaticResource boxSize}"
                                 HeightRequest="{StaticResource boxSize}"
                                 Color="{Binding Color}" />

                        <StackLayout Padding="5, 0, 0, 0"
                                     VerticalOptions="Center">

                            <Label Text="{Binding FriendlyName}"
                                   FontAttributes="Bold"
                                   FontSize="Medium" />

                            <StackLayout Orientation="Horizontal"
                                         Spacing="0">
                                <Label Text="{Binding Color.R,
                                       Converter={StaticResource intConverter},
                                       ConverterParameter=255,
                                       StringFormat='R={0:X2}'}" />

                                <Label Text="{Binding Color.G,
                                       Converter={StaticResource intConverter},
                                       ConverterParameter=255,
                                       StringFormat=', G={0:X2}'}" />

                                <Label Text="{Binding Color.B,
                                       Converter={StaticResource intConverter},
                                       ConverterParameter=255,
                                       StringFormat=', B={0:X2}'}" />
                            </StackLayout>
                        </StackLayout>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

BoxView의 크기와 ListView 행의 높이를 정의하기 위해 OnPlatform을 사용합니다.Notice the use of OnPlatform to define the size of a BoxView and the height of the ListView rows. 모든 플랫폼의 값은 동일하지만 태그를 다른 값으로 쉽게 조정하여 표시되는 것을 미세 조정할 수 있습니다.Although the values for all the platforms are the same, the markup could easily be adapted for other values to fine-tune the display.

바인딩 값 변환기Binding Value Converters

이전 ListView 데모 XAML 파일은 Xamarin.Forms Color 구조체의 개별 R, G, B 속성을 표시합니다.The previous ListView Demo XAML file displays the individual R, G, and B properties of the Xamarin.Forms Color structure. 해당 속성은 double 유형이고 범위는 0에서 1까지입니다.These properties are of type double and range from 0 to 1. 16 진수 값을 표시하려는 경우 "X2" 형식 지정과 함께 단순히 StringFormat을 사용할 수 없습니다.If you want to display the hexadecimal values, you can’t simply use StringFormat with an “X2” formatting specification. 그것은 정수에만 작동하고, 게다가 double 값에는 255를 곱해야 합니다.That only works for integers and besides, the double values need to be multiplied by 255.

이 사소한 문제는 바인딩 변환기라고도 하는 값 변환기(value converter) 로 해결되었습니다.This little problem was solved with a value converter, also called a binding converter. 이 클래스는 IValueConverter인터페이스를 구현하는 클래스입니다. 즉,ConvertConvertBack이라는 두 가지 메서드를 가지고 있습니다.This is a class that implements the IValueConverter interface, which means it has two methods named Convert and ConvertBack. Convert 메서드는 값이 원본(source)에서 대상(target)으로 전달될 때 호출됩니다. ConvertBack 메서드는 OneWayToSource 또는 TwoWay 바인딩 내에서 대상에서 원본으로 전송을 위해 호출됩니다.The Convert method is called when a value is transferred from source to target; the ConvertBack method is called for transfers from target to source in OneWayToSource or TwoWay bindings:

using System;
using System.Globalization;
using Xamarin.Forms;

namespace XamlSamples
{
    class DoubleToIntConverter : IValueConverter
    {
        public object Convert(object value, Type targetType,
                              object parameter, CultureInfo culture)
        {
            double multiplier;

            if (!Double.TryParse(parameter as string, out multiplier))
                multiplier = 1;

            return (int)Math.Round(multiplier * (double)value);
        }

        public object ConvertBack(object value, Type targetType,
                                  object parameter, CultureInfo culture)
        {
            double divider;

            if (!Double.TryParse(parameter as string, out divider))
                divider = 1;

            return ((double)(int)value) / divider;
        }
    }
}

바인딩이 원본에서 대상으로 오직 단 방향이므로, ConvertBack 메서드는 이 프로그램에서 역할을 하지 않습니다.The ConvertBack method does not play a role in this program because the bindings are only one way from source to target.

바인딩은 바인딩 변환기를 Converter 속성으로 참조합니다.A binding references a binding converter with the Converter property. 바인딩 변환기는 ConverterParameter 속성으로 지정된 매개 변수를 받아들일 수도 있습니다.A binding converter can also accept a parameter specified with the ConverterParameter property. 몇 가지 다양한 기능에 대한 승수를 지정하는 방법입니다.For some versatility, this is how the multiplier is specified. 바인딩 변환기는 변환 매개 변수에서 유효한 double 값을 확인합니다.The binding converter checks the converter parameter for a valid double value.

다음과 같이 변환기는 리소스 사전에서 인스턴스화되므로 여러 바인딩 간에 공유될 수 있습니다.The converter is instantiated in the resource dictionary so it can be shared among multiple bindings:

<local:DoubleToIntConverter x:Key="intConverter" />

세 개의 데이터 바인딩이 단일 인스턴스를 참조합니다.Three data bindings reference this single instance. 다음과 같이 Binding 태그 확장은 내부에 StaticResource 태그 확장을 포함합니다.Notice that the Binding markup extension contains an embedded StaticResource markup extension:

<Label Text="{Binding Color.R,
                      Converter={StaticResource intConverter},
                      ConverterParameter=255,
                      StringFormat='R={0:X2}'}" />

결과 다음과 같습니다.Here’s the result:

ListView는 기본 데이터에서 동적으로 발생할 수 있는 변경 사항을 처리하는 데 상당히 정교하지만 특정 단계를 수행할 때만 가능합니다.The ListView is quite sophisticated in handling changes that might dynamically occur in the underlying data, but only if you take certain steps. ListViewItemsSource 속성에 할당된 항목의 컬렉션이 런타임 중에 변경되면(즉, 항목이 컬렉션에서 추가되거나 제거될 수 있는 경우), 해당 항목에 대해 ObservableCollection 클래스를 사용하십시오.If the collection of items assigned to the ItemsSource property of the ListView changes during runtime—that is, if items can be added to or removed from the collection—use an ObservableCollection class for these items. ObservableCollectionINotifyCollectionChanged 인터페이스를 구현하고, ListViewCollectionChanged 이벤트를 위한 처리기를 설치합니다.ObservableCollection implements the INotifyCollectionChanged interface, and ListView will install a handler for the CollectionChanged event.

항목 자체의 속성이 런타임 중에 변경되면, 컬렉션의 항목은 INotifyPropertyChanged 인터페이스를 구현하고, PropertyChanged 이벤트를 사용하여 속성 값 변경 사항에 대해 신호합니다.If properties of the items themselves change during runtime, then the items in the collection should implement the INotifyPropertyChanged interface and signal changes to property values using the PropertyChanged event. 해당 내용은 이 시리즈의 다음 부분인 5부. 데이터 바인딩부터 MVVM까지에서 설명합니다.This is demonstrated in the next part of this series, Part 5. From Data Binding to MVVM.

요약Summary

데이터 바인딩은 페이지 내의 두 개체 간, 또는 시각적 개체와 기본 데이터 사이의 속성을 연결하는 강력한 메커니즘을 제공합니다.Data bindings provide a powerful mechanism for linking properties between two objects within a page, or between visual objects and underlying data. 그러나 응응 프로그램이 데이터 원본(sources)으로 작업하기 시작하면, 인기 있는 응용 프로그램 아키텍처 패턴이 유용한 패러다임으로 부상하기 시작합니다.But when the application begins working with data sources, a popular application architectural pattern begins to emerge as a useful paradigm. 이에 대해서는 5부. 데이터 바인딩부터 MVVM까지에서 다룹니다.This is covered in Part 5. From Data Bindings to MVVM.