2부.Part 2. 필수 XAML 구문Essential XAML Syntax

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

XAML은 주로 인스턴스화 및 초기화 개체에 대 한 설계 되었습니다. 하지만 종종 속성을 XML 문자열로 쉽게 표현할 수 없는 복잡한 개체 속성으로 설정해야 하고 하나의 클래스에 의해 정의된 속성을 자식 클래스에 설정해야 하는 경우가 있습니다. 따라서 속성 요소 및 연결 속성이라는 필수 XAML 구문 기능이 필요합니다.XAML is mostly designed for instantiating and initializing objects. But often, properties must be set to complex objects that cannot easily be represented as XML strings, and sometimes properties defined by one class must be set on a child class. These two needs require the essential XAML syntax features of property elements and attached properties.

속성 요소Property Elements

XAML에서 클래스의 속성은 일반적으로 다음과 같이 XML 특성으로 설정됩니다.In XAML, properties of classes are normally set as XML attributes:

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="Large"
       TextColor="Aqua" />

그러나 XAML에서 속성을 설정하는 대체 방법이 있습니다.However, there is an alternative way to set a property in XAML. TextColor를 사용하여 해당 대안을 시도해 보려면 먼저 다음과 같이 기존 TextColor 설정을 삭제하십시오.To try this alternative with TextColor, first delete the existing TextColor setting:

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="Large" />

다음과 같이 시작 및 끝 태그로 분리하여 Label 태그 빈 요소를 엽니다.Open up the empty-element Label tag by separating it into start and end tags:

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="Large">

</Label>

이 태그 안에 다음과 같이 점으로 구분된 클래스 이름과 속성 이름으로 구성된 시작 및 끝 태그를 추가합니다.Within these tags, add start and end tags that consist of the class name and a property name separated by a period:

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="Large">
    <Label.TextColor>

    </Label.TextColor>
</Label>

다음과 같이 해당 새 태그의 내용으로 속성 값을 설정합니다.Set the property value as content of these new tags, like this:

<Label Text="Hello, XAML!"
       VerticalOptions="Center"
       FontAttributes="Bold"
       FontSize="Large">
    <Label.TextColor>
        Aqua
    </Label.TextColor>
</Label>

TextColor 속성을 지정하는 해당 두 방법은 기능적으로 동일하지만, 속성을 실제로 두 번 설정하게 되고 모호할 수 있으므로 동일한 속성에 두 가지 방법을 사용하지 마십시오.These two ways to specify the TextColor property are functionally equivalent, but don't use the two ways for the same property because that would effectively be setting the property twice, and might be ambiguous.

해당 새 구문으로 다음과 같은 몇 가지 편리한 용어를 사용할 수 있습니다.With this new syntax, some handy terminology can be introduced:

  • Label개체 요소입니다.Label is an object element. XML 요소로 표현된 Xamarin.Forms 개체입니다.It is a Xamarin.Forms object expressed as an XML element.
  • Text, VerticalOptions, FontAttributesFontSize속성 특성 입니다.Text, VerticalOptions, FontAttributes and FontSize are property attributes. 이들은 XML 특성으로 표현된 Xamarin.Forms 속성입니다.They are Xamarin.Forms properties expressed as XML attributes.
  • 해당 마지막 조각에서 TextColor속성 요소가 되었습니다.In that final snippet, TextColor has become a property element. 이는 Xamarin.Forms 속성이지만 이제 XML 요소입니다.It is a Xamarin.Forms property but it is now an XML element.

속성 요소의 정의는 처음에는 XML 구문을 위반하는 것처럼 보일 수 있지만 그렇지 않습니다.The definition of property elements might at first seem to be a violation of XML syntax, but it’s not. 마침표는 XML에서 특별한 의미가 없습니다.The period has no special meaning in XML. XML 디코더에서 Label.TextColor는 단순히 일반적인 자식 요소입니다.To an XML decoder, Label.TextColor is simply a normal child element.

하지만 XAML에서는 해당 구문이 매우 특별합니다.In XAML, however, this syntax is very special. 속성 요소에 대한 규칙 중 하나는 Label.TextColor 태그에 다른 것을 표시할 수 없다는 것입니다.One of the rules for property elements is that nothing else can appear in the Label.TextColor tag. 속성의 값은 항상 속성 요소 시작 태그와 종료 태그 사이의 내용으로 정의됩니다.The value of the property is always defined as content between the property-element start and end tags.

다음과 같이 둘 이상의 속성에서 속성 요소 구문을 사용할 수 있습니다.You can use property-element syntax on more than one property:

<Label Text="Hello, XAML!"
       VerticalOptions="Center">
    <Label.FontAttributes>
        Bold
    </Label.FontAttributes>
    <Label.FontSize>
        Large
    </Label.FontSize>
    <Label.TextColor>
        Aqua
    </Label.TextColor>
</Label>

또는 다음과 같이 모든 속성에 대한 속성 요소 구문을 사용할 수 있습니다.Or you can use property-element syntax for all the properties:

<Label>
    <Label.Text>
        Hello, XAML!
    </Label.Text>
    <Label.FontAttributes>
        Bold
    </Label.FontAttributes>
    <Label.FontSize>
        Large
    </Label.FontSize>
    <Label.TextColor>
        Aqua
    </Label.TextColor>
    <Label.VerticalOptions>
        Center
    </Label.VerticalOptions>
</Label>

처음에 속성 요소 구문이 비교적 꽤 단순한 것에 대한 불필요하게 장황한 대체 수단으로 여겨질 수 있고, 해당 예제에서는 확실히 그렇습니다.At first, property-element syntax might seem like an unnecessary long-winded replacement for something comparatively quite simple, and in these examples that is certainly the case.

그러나 속성의 값이 너무 복잡해서 간단한 문자열로 표현할 수 없으면 속성 요소 구문이 필수적입니다.However, property-element syntax becomes essential when the value of a property is too complex to be expressed as a simple string. 속성 요소 태그 내에서 다른 개체를 인스턴스화하고 해당 속성을 설정할 수 있습니다.Within the property-element tags you can instantiate another object and set its properties. 예를 들어 다음과 같이 속성 설정을 사용하여 VerticalOptions와 같은 속성을 LayoutOptions 값으로 명시적으로 설정할 수 있습니다.For example, you can explicitly set a property such as VerticalOptions to a LayoutOptions value with property settings:

<Label>
    ...
    <Label.VerticalOptions>
        <LayoutOptions Alignment="Center" />
    </Label.VerticalOptions>
</Label>

다른 예제입니다. 합니다 Grid 라는 두 속성이 RowDefinitionsColumnDefinitions합니다.Another example: The Grid has two properties named RowDefinitions and ColumnDefinitions. 해당 두 속성은 RowDefinitionCollectionColumnDefinitionCollection 형식이며, 이들은 RowDefinitionColumnDefinition 개체의 컬렉션입니다.These two properties are of type RowDefinitionCollection and ColumnDefinitionCollection, which are collections of RowDefinition and ColumnDefinition objects. 이러한 컬렉션을 설정하려면 속성 요소 구문을 사용해야 합니다.You need to use property element syntax to set these collections.

다음은 GridDemoPage 클래스에 대한 XAML 파일의 시작 부분으로, RowDefinitionsColumnDefinitions 컬렉션에 대한 속성 요소 태그를 보여줍니다.Here’s the beginning of the XAML file for a GridDemoPage class, showing the property element tags for the RowDefinitions and ColumnDefinitions collections:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.GridDemoPage"
             Title="Grid Demo Page">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>
        ...
    </Grid>
</ContentPage>

자동 크기 조정 셀, 픽셀 너비 및 높이 셀 및 별 설정을 정의하기 위한 약식 구문을 확인하십시오.Notice the abbreviated syntax for defining auto-sized cells, cells of pixel widths and heights, and star settings.

연결 속성Attached Properties

방금 살펴 보았듯이 행과 열을 정의하기 위해 GridRowDefinitionsColumnDefinitions 컬렉션에 대한 속성 요소가 필요합니다.You've just seen that the Grid requires property elements for the RowDefinitions and ColumnDefinitions collections to define the rows and columns. 그러나 프로그래머가 Grid의 각 자식이 위치하는 행과 열을 나타낼 방법이 있어야 합니다.However, there must also be some way for the programmer to indicate the row and column where each child of the Grid resides.

다음 특성을 사용하여 Grid의 각 자식에 대한 태그 내에서의 해당 자식의 행과 열을 지정합니다.Within the tag for each child of the Grid you specify the row and column of that child using the following attributes:

  • Grid.Row
  • Grid.Column

해당 특성의 기본값은 0입니다.The default values of these attributes are 0. 다음의 특성을 사용하여 해당 속성을 가진 자식이 둘 이상의 행 또는 열에 걸쳐 있는지 여부를 나타낼 수도 있습니다.You can also indicate if a child spans more than one row or column with these attributes:

  • Grid.RowSpan
  • Grid.ColumnSpan

해당 두 특성의 기본값은 1입니다.These two attributes have default values of 1.

다음은 전체 GridDemoPage.xaml 파일입니다.Here’s the complete GridDemoPage.xaml file:

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

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>

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

        <Label Text="Autosized cell"
               Grid.Row="0" Grid.Column="0"
               TextColor="White"
               BackgroundColor="Blue" />

        <BoxView Color="Silver"
                 HeightRequest="0"
                 Grid.Row="0" Grid.Column="1" />

        <BoxView Color="Teal"
                 Grid.Row="1" Grid.Column="0" />

        <Label Text="Leftover space"
               Grid.Row="1" Grid.Column="1"
               TextColor="Purple"
               BackgroundColor="Aqua"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />

        <Label Text="Span two rows (or more if you want)"
               Grid.Row="0" Grid.Column="2" Grid.RowSpan="2"
               TextColor="Yellow"
               BackgroundColor="Blue"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />

        <Label Text="Span two columns"
               Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2"
               TextColor="Blue"
               BackgroundColor="Yellow"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />

        <Label Text="Fixed 100x100"
               Grid.Row="2" Grid.Column="2"
               TextColor="Aqua"
               BackgroundColor="Red"
               HorizontalTextAlignment="Center"
               VerticalTextAlignment="Center" />

    </Grid>
</ContentPage>

Grid.RowGrid.Column을 0으로 설정하는 것은 필요하지 않지만, 명확히 하기 위해 일반적으로 포함합니다.The Grid.Row and Grid.Column settings of 0 are not required but are generally included for purposes of clarity.

해당 모양은 다음과 같습니다.Here’s what it looks like:

구문으로만 미루어 보면, 해당 Grid.Row, Grid.Column, Grid.RowSpanGrid.ColumnSpan 속성은 정적(static) 필드 또는 Grid의 특성으로 보이지만, 흥미롭게도 GridRow, Column, RowSpan 또는 ColumnSpan 이름을 가진 어떤 것도 정의하지 않습니다.Judging solely from the syntax, these Grid.Row, Grid.Column, Grid.RowSpan, and Grid.ColumnSpan attributes appear to be static fields or properties of Grid, but interestingly enough, Grid does not define anything named Row, Column, RowSpan, or ColumnSpan.

대신 GridRowProperty, ColumnProperty, RowSpanPropertyColumnSpanProperty라는 4개의 바인딩 가능한 속성을 정의합니다.Instead, Grid defines four bindable properties named RowProperty, ColumnProperty, RowSpanProperty, and ColumnSpanProperty. 해당 속성은 연결 속성이라는 특별한 유형의 바인딩 가능한 속성입니다.These are special types of bindable properties known as attached properties. 이는 Grid 클래스에 의해 정의되지만 Grid의 자식에 설정됩니다.They are defined by the Grid class but set on children of the Grid.

코드에서 해당 연결 속성을 사용하려는 경우, Grid 클래스는 SetRow, GetColumn등의 정적(static) 메서드를 제공합니다.When you wish to use these attached properties in code, the Grid class provides static methods named SetRow, GetColumn, and so forth. 그러나 XAML에서 해당 연결 속성은 간단한 속성 이름을 사용하여 Grid의 자식에서 특성으로 설정됩니다.But in XAML, these attached properties are set as attributes in the children of the Grid using simple properties names.

연결 속성은 항상 XAML 파일에서 클래스와 속성 이름을 마침표로 구분하여 포함하는 특성으로 인식할 수 있습니다.Attached properties are always recognizable in XAML files as attributes containing both a class and a property name separated by a period. 하나의 클래스(이 예제의 경우 Grid)에서 정의되었지만, 다른 개체(여기서는 Grid의 자식)에 연결되었기 때문에 연결 속성이라고 합니다.They are called attached properties because they are defined by one class (in this case, Grid) but attached to other objects (in this case, children of the Grid). 레이아웃하는 동안, Grid는 각 자식을 배치할 위치를 알기 위해 해당 연결 속성의 값을 조사할 수 있습니다.During layout, the Grid can interrogate the values of these attached properties to know where to place each child.

AbsoluteLayout 클래스는 LayoutBoundsLayoutFlags라는 두 개의 연결 속성을 정의합니다.The AbsoluteLayout class defines two attached properties named LayoutBounds and LayoutFlags. 다음은 AbsoluteLayout의 비례 위치 지정 및 크기 조정 기능을 사용하여 구현된 체스판 패턴입니다.Here’s a checkerboard pattern realized using the proportional positioning and sizing features of AbsoluteLayout:

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

    <AbsoluteLayout BackgroundColor="#FF8080">
        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="0.33, 0, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="1, 0, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="0, 0.33, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="0.67, 0.33, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="0.33, 0.67, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="1, 0.67, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="0, 1, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

        <BoxView Color="#8080FF"
                 AbsoluteLayout.LayoutBounds="0.67, 1, 0.25, 0.25"
                 AbsoluteLayout.LayoutFlags="All" />

  </AbsoluteLayout>
</ContentPage>

화면은 다음과 같습니다.And here it is:

이런 경우 XAML 사용의 지혜로움에 의문을 제기할 수 있습니다.For something like this, you might question the wisdom of using XAML. LayoutBounds 사각형의 반복 및 규칙성으로 보아 코드에서 구현되는 편이 낫지 않았나 생각할 수 있습니다.Certainly, the repetition and regularity of the LayoutBounds rectangle suggests that it might be better realized in code.

이는 합당한 우려이며, 사용자 인터페이스를 정의하는 경우 코드와 태그의 균형을 잘 맞추면 문제가 없습니다.That’s certainly a legitimate concern, and there’s no problem with balancing the use of code and markup when defining your user interfaces. XAML에서 일부 시각적 개체를 정의하고, 그런 다음 코드 숨김 파일의 생성자를 사용하여 루프에서 더 잘 생성할 수 있는 몇 가지 시각적 개체를 추가하는 것이 쉽습니다.It’s easy to define some of the visuals in XAML and then use the constructor of the code-behind file to add some more visuals that might be better generated in loops.

콘텐츠 속성Content Properties

이전 예제에서 StackLayout, GridAbsoluteLayout 개체는 ContentPageContent 속성으로 설정되었고, 해당 레이아웃의 자식들은 실제로 Children 컬렉션의 항목들입니다.In the previous examples, the StackLayout, Grid, and AbsoluteLayout objects are set to the Content property of the ContentPage, and the children of these layouts are actually items in the Children collection. 아직 해당 ContentChildren 속성은 XAML 파일에 없습니다.Yet these Content and Children properties are nowhere in the XAML file.

다음의 XamlPlusCode 예제와 같이 ContentChildren 속성을 속성 요소로 포함할 수 있습니다.You can certainly include the Content and Children properties as property elements, such as in the XamlPlusCode sample:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.XamlPlusCodePage"
             Title="XAML + Code Page">
    <ContentPage.Content>
        <StackLayout>
            <StackLayout.Children>
                <Slider VerticalOptions="CenterAndExpand"
                        ValueChanged="OnSliderValueChanged" />

                <Label x:Name="valueLabel"
                       Text="A simple Label"
                       FontSize="Large"
                       HorizontalOptions="Center"
                       VerticalOptions="CenterAndExpand" />

                <Button Text="Click Me!"
                      HorizontalOptions="Center"
                      VerticalOptions="CenterAndExpand"
                      Clicked="OnButtonClicked" />
            </StackLayout.Children>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

현실적인 질문 다음과 같습니다. 이러한 속성 요소 이유는 무엇 인가요 되지 는 XAML 파일에 필요한?The real question is: Why are these property elements not required in the XAML file?

XAML에서 사용하기 위해 Xamarin.Forms에 정의된 요소는 클래스의 ContentProperty 특성에 플래그가 지정된 하나의 속성을 가질 수 있습니다.Elements defined in Xamarin.Forms for use in XAML are allowed to have one property flagged in the ContentProperty attribute on the class. 온라인 Xamarin.Forms 문서에서 ContentPage 클래스를 검색하면 해당 특성을 볼 수 있습니다.If you look up the ContentPage class in the online Xamarin.Forms documentation, you’ll see this attribute:

[Xamarin.Forms.ContentProperty("Content")]
public class ContentPage : TemplatedPage

즉, Content 속성 요소 태그가 필요하지 않다는 의미입니다.This means that the Content property-element tags are not required. ContentPage 태그의 시작과 끝 사이에 나타나는 모든 XML 내용은 Content 속성에 할당되는 것으로 간주됩니다.Any XML content that appears between the start and end ContentPage tags is assumed to be assigned to the Content property.

StackLayout, Grid, AbsoluteLayoutRelativeLayout은 모두 Layout<View>에서 파생되었으며, Xamarin.Forms 문서에서 Layout<T>를 검색하면 다음과 같이 또 다른 ContentProperty 특성을 찾을 수 있습니다.StackLayout, Grid, AbsoluteLayout, and RelativeLayout all derive from Layout<View>, and if you look up Layout<T> in the Xamarin.Forms documentation, you’ll see another ContentProperty attribute:

[Xamarin.Forms.ContentProperty("Children")]
public abstract class Layout<T> : Layout ...

이렇게 하면 레이아웃의 컨텐츠를 명시적으로 Children 속성 요소 태그 없이 Children 컬렉션에 자동으로 추가할 수 있습니다.That allows content of the layout to be automatically added to the Children collection without explicit Children property-element tags.

다른 클래스들은 ContentProperty 특성 정의가 있습니다.Other classes also have ContentProperty attribute definitions. 예를 들어, Label의 콘텐츠 속성은 Text 입니다.For example, the content property of Label is Text. 다른 것들은 API 설명서를 확인하십시오.Check the API documentation for others.

OnPlatform 사용 시의 플랫폼별 차이Platform Differences with OnPlatform

단일 페이지 응용 프로그램에서는 iOS 상태 표시줄을 덮어쓰지 않도록 페이지에서 Padding 속성을 설정하는 것이 일반적입니다.In single page applications, it is common to set the Padding property on the page to avoid overwriting the iOS status bar. 이를 위해 다음과 같이 코드에서 Device.RuntimePlatform 속성을 사용할 수 있습니다.In code, you can use the Device.RuntimePlatform property for this purpose:

if (Device.RuntimePlatform == Device.iOS)
{
    Padding = new Thickness(0, 20, 0, 0);
}

XAML 사용 하 여 비슷한 수행할 수도 있습니다는 OnPlatform 하 고 On 클래스입니다.You can also do something similar in XAML using the OnPlatform and On classes. 먼저 페이지의 상단 근처의 Padding 속성을 위해 다음과 같이 속성 요소를 추가합니다.First include property elements for the Padding property near the top of the page:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>

    </ContentPage.Padding>
    ...
</ContentPage>

해당 태그 안에 OnPlatform 태그를 포함하십시오.Within these tags, include an OnPlatform tag. OnPlatform은 제네릭 클래스입니다.OnPlatform is a generic class. 제네릭(generic) 형식 인수를 지정해야 하고, 이 경우에는 Padding 속성 형식인 Thickness입니다.You need to specify the generic type argument, in this case, Thickness, which is the type of Padding property. 다행스럽게도 x:TypeArguments라는 제네릭 인수를 정의하는 XAML 특성이 있습니다.Fortunately, there’s a XAML attribute specifically to define generic arguments called x:TypeArguments. 속성 유형을 매칭하는 설정은 다음과 같습니다.This should match the type of the property you're setting:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">

        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

OnPlatform에는 On 개체의 IListPlatforms라는 속성이 있습니다.OnPlatform has a property named Platforms that is an IList of On objects. 해당 속성에 대한 속성 요소 태그는 다음과 같습니다.Use property element tags for that property:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <OnPlatform.Platforms>

            </OnPlatform.Platforms>
        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

이제 On 요소를 추가합니다.Now add On elements. 각각에 대해 다음과 같이 Platform 속성 및 Value 속성을 설정하여 Thickness 속성을 다음과 같이 설정합니다.For each one set the Platform property and the Value property to markup for the Thickness property:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <OnPlatform.Platforms>
                <On Platform="iOS" Value="0, 20, 0, 0" />
                <On Platform="Android" Value="0, 0, 0, 0" />
                <On Platform="UWP" Value="0, 0, 0, 0" />
            </OnPlatform.Platforms>
        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

해당 태그는 단순화할 수 있습니다.This markup can be simplified. OnPlatform의 콘텐츠 속성은 Platforms이므로 해당 속성 요소 태그는 다음과 같이 제거할 수 있습니다.The content property of OnPlatform is Platforms, so those property-element tags can be removed:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS" Value="0, 20, 0, 0" />
            <On Platform="Android" Value="0, 0, 0, 0" />
            <On Platform="UWP" Value="0, 0, 0, 0" />
        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

OnPlatform 속성은 IList<string> 유형이므로 다음과 같이 값이 동일한 경우 여러 플랫폼을 포함할 수 있습니다.The Platform property of On is of type IList<string>, so you can include multiple platforms if the values are the same:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS" Value="0, 20, 0, 0" />
            <On Platform="Android, UWP" Value="0, 0, 0, 0" />
        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

Android 및 UWP의 Padding은 기본값으로 설정되어 있으므로, 다음과 같이 해당 태그는 제거할 수 있습니다.Because Android and UWP are set to the default value of Padding, that tag can be removed:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS" Value="0, 20, 0, 0" />
        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

이는 XAML에서 플랫폼 종속적인 Padding 속성을 설정하는 표준 방법입니다.This is the standard way to set a platform-dependent Padding property in XAML. Value 설정을 단일 문자열로 표현할 수 없는 경우, 해당 속성 요소를 다음과 같이 정의할 수 있습니다.If the Value setting cannot be represented by a single string, you can define property elements for it:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...">

    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS">
                <On.Value>
                    0, 20, 0, 0
                </On.Value>
            </On>
        </OnPlatform>
    </ContentPage.Padding>
  ...
</ContentPage>

참고

OnPlatform 태그 확장 사용할 수도 있습니다 XAML에서 플랫폼별 기준 UI 모양을 사용자 지정할 수 있습니다.The OnPlatform markup extension can also be used in XAML to customize UI appearance on a per-platform basis. 동일한 기능을 제공 합니다 OnPlatformOn 클래스 하지만 보다 간결 하 게 표현 합니다.It provides the same functionality as the OnPlatform and On classes, but with a more concise representation. 자세한 내용은 OnPlatform 태그 확장합니다.For more information, see OnPlatform Markup Extension.

요약Summary

속성 요소 및 연결 속성을 사용하여 상당 부분의 기본 XAML 구문을 설정하였습니다.With property elements and attached properties, much of the basic XAML syntax has been established. 그러나 때로는 리소스 사전과 같은 간접 방식으로 개체 속성을 설정해야 합니다.However, sometimes you need to set properties to objects in an indirect manner, for example, from a resource dictionary. 해당 접근 방식은 다음 부분인 3부. XAML 태그 확장에서 다룹니다.This approach is covered in the next part, Part 3. XAML Markup Extensions.