2부. 필수 XAML 구문
XAML은 주로 개체를 인스턴스화하고 초기화하도록 설계되었습니다. 그러나 XML 문자열로 쉽게 나타낼 수 없는 복합 개체로 속성을 설정해야 하는 경우가 많으며, 경우에 따라 한 클래스에서 정의된 속성을 자식 클래스에서 설정해야 합니다. 이러한 두 요구 사항에는 속성 요소 및 연결된 속성의 필수 XAML 구문 기능이 필요합니다.
속성 요소
XAML에서 클래스의 속성은 일반적으로 XML 특성으로 설정됩니다.
<Label Text="Hello, XAML!"
VerticalOptions="Center"
FontAttributes="Bold"
FontSize="Large"
TextColor="Aqua" />
그러나 XAML에서 속성을 설정하는 다른 방법이 있습니다. 이 대안을 TextColor
사용하려면 먼저 기존 TextColor
설정을 삭제합니다.
<Label Text="Hello, XAML!"
VerticalOptions="Center"
FontAttributes="Bold"
FontSize="Large" />
시작 및 끝 태그로 구분하여 빈 요소 Label
태그를 엽니다.
<Label Text="Hello, XAML!"
VerticalOptions="Center"
FontAttributes="Bold"
FontSize="Large">
</Label>
이러한 태그 내에서 클래스 이름과 마침표로 구분된 속성 이름으로 구성된 시작 및 끝 태그를 추가합니다.
<Label Text="Hello, XAML!"
VerticalOptions="Center"
FontAttributes="Bold"
FontSize="Large">
<Label.TextColor>
</Label.TextColor>
</Label>
다음과 같이 속성 값을 새 태그의 콘텐츠로 설정합니다.
<Label Text="Hello, XAML!"
VerticalOptions="Center"
FontAttributes="Bold"
FontSize="Large">
<Label.TextColor>
Aqua
</Label.TextColor>
</Label>
속성을 지정 TextColor
하는 이러한 두 가지 방법은 기능적으로 동일하지만 동일한 속성에 대해 두 가지 방법을 사용하지 마세요. 이는 속성을 효과적으로 두 번 설정하며 모호할 수 있기 때문입니다.
이 새로운 구문을 사용하면 몇 가지 편리한 용어를 도입할 수 있습니다.
Label
는 개체 요소입니다. Xamarin.Forms XML 요소로 표현되는 개체입니다.Text
,VerticalOptions
및FontAttributes
FontSize
속성 특성입니다. XML 특성으로 표현되는 속성입니다 Xamarin.Forms .- 마지막 코드
TextColor
조각에서 속성 요소가 되었습니다. Xamarin.Forms 속성이지만 이제 XML 요소입니다.
속성 요소의 정의는 처음에는 XML 구문을 위반하는 것처럼 보일 수 있지만 그렇지 않습니다. 마침표는 XML에서 특별한 의미가 없습니다. XML 디코더 Label.TextColor
의 경우 단순히 일반 자식 요소입니다.
그러나 XAML에서는 이 구문이 매우 특별합니다. 속성 요소에 대한 규칙 중 하나는 태그에 Label.TextColor
다른 어떤 것도 표시할 수 없다는 것입니다. 속성 값은 항상 속성 요소 시작 태그와 끝 태그 사이의 콘텐츠로 정의됩니다.
두 개 이상의 속성에 속성 요소 구문을 사용할 수 있습니다.
<Label Text="Hello, XAML!"
VerticalOptions="Center">
<Label.FontAttributes>
Bold
</Label.FontAttributes>
<Label.FontSize>
Large
</Label.FontSize>
<Label.TextColor>
Aqua
</Label.TextColor>
</Label>
또는 모든 속성에 속성 요소 구문을 사용할 수 있습니다.
<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>
처음에 속성 요소 구문은 비교적 매우 간단한 항목에 대한 불필요한 긴 바람 대체처럼 보일 수 있으며, 이러한 예에서는 확실히 그 예입니다.
그러나 속성 값이 너무 복잡하여 단순 문자열로 표현될 수 없는 경우 속성 요소 구문이 필수적입니다. 속성 요소 태그 내에서 다른 개체를 인스턴스화하고 해당 속성을 설정할 수 있습니다. 예를 들어 속성 설정이 있는 값과 같은 VerticalOptions
LayoutOptions
속성을 명시적으로 설정할 수 있습니다.
<Label>
...
<Label.VerticalOptions>
<LayoutOptions Alignment="Center" />
</Label.VerticalOptions>
</Label>
또 다른 예: 두 Grid
개의 속성이 이름이 지정 RowDefinitions
되고 ColumnDefinitions
. 이러한 두 속성은 형식 RowDefinitionCollection
이며 컬렉션과 ColumnDefinition
개체입니다 RowDefinition
ColumnDefinitionCollection
. 이러한 컬렉션을 설정하려면 속성 요소 구문을 사용해야 합니다.
다음은 클래스에 대한 GridDemoPage
XAML 파일의 시작 부분으로, 컬렉션 및 ColumnDefinitions
컬렉션에 대한 속성 요소 태그를 RowDefinitions
보여 줍니다.
<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>
자동 크기 셀, 픽셀 너비 및 높이의 셀 및 별 설정을 정의하기 위한 약어 구문을 확인합니다.
연결된 속성
행과 열을 정의하려면 컬렉션 및 ColumnDefinitions
컬렉션에 RowDefinitions
대한 속성 요소가 필요하다는 것을 살펴보 Grid
았습니다. 그러나 프로그래머가 각 자식 Grid
이 있는 행과 열을 나타내는 방법도 있어야 합니다.
각 자식의 Grid
태그 내에서 다음 특성을 사용하여 해당 자식의 행과 열을 지정합니다.
Grid.Row
Grid.Column
이러한 특성의 기본값은 0입니다. 자식이 다음 특성을 사용하여 둘 이상의 행 또는 열에 걸쳐 있는지 여부를 나타낼 수도 있습니다.
Grid.RowSpan
Grid.ColumnSpan
이러한 두 특성의 기본값은 1입니다.
전체 GridDemoPage.xaml 파일은 다음과 같습니다.
<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>
0의 설정은 Grid.Row
Grid.Column
필요하지 않지만 일반적으로 명확성을 위해 포함됩니다.
모양은 다음과 같습니다.
구문에서만 판단하면 이러한 , , 및 특성이 정적 필드 또는 속성인 Grid
것처럼 보이지만 흥미롭게 Grid
도 이름이 지정된 Row
RowSpan
ColumnSpan
Column
것을 정의하지는 않습니다.Grid.ColumnSpan
Grid.RowSpan
Grid.Column
Grid.Row
대신 , Grid
및 ColumnSpanProperty
.라는 RowProperty
ColumnProperty
RowSpanProperty
네 개의 바인딩 가능한 속성을 정의합니다. 연결된 속성이라고 하는 바인딩 가능한 속성의 특수 형식입니다. 클래스에 의해 정의되지만 해당 Grid
클래스의 자식에 설정됩니다 Grid
.
코드에서 이러한 연결된 속성을 사용하려는 경우 클래스는 Grid
명명된 SetRow
GetColumn
정적 메서드 등을 제공합니다. 그러나 XAML에서 이러한 연결된 속성은 using 단순 속성 이름의 자식 Grid
에서 특성으로 설정됩니다.
연결된 속성은 클래스와 속성 이름을 마침표로 구분하여 포함하는 특성으로 XAML 파일에서 항상 인식할 수 있습니다. 연결된 속성은 한 클래스(이 경우Grid
)로 정의되지만 다른 개체(이 경우의 Grid
자식)에 연결되기 때문에 연결된 속성이라고 합니다. 레이아웃 중에 Grid
이러한 연결된 속성의 값을 심문하여 각 자식의 위치를 알 수 있습니다.
클래스는 AbsoluteLayout
명명 LayoutBounds
된 두 개의 연결된 속성과 LayoutFlags
. 다음은 다음의 비례 위치 지정 및 크기 조정 기능을 사용하여 구현된 검사erboard 패턴입니다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>
결과는 다음과 같습니다.
이와 같은 경우 XAML을 사용하는 지혜에 의문을 제기할 수 있습니다. 물론 직사각형의 LayoutBounds
반복과 규칙성은 코드에서 더 잘 실현될 수 있음을 시사합니다.
이는 확실히 합법적인 문제이며 사용자 인터페이스를 정의할 때 코드 및 태그 사용의 균형을 맞추는 데 아무런 문제가 없습니다. XAML에서 일부 시각적 개체를 정의한 다음 코드 숨김 파일의 생성자를 사용하여 루프에서 더 잘 생성될 수 있는 시각적 개체를 추가할 수 있습니다.
콘텐츠 속성
이전 예제StackLayout
에서 , Grid
및 AbsoluteLayout
개체는 해당 속성ContentPage
으로 Content
설정되며 이러한 레이아웃의 자식은 실제로 컬렉션의 Children
항목입니다. 그러나 이러한 Content
속성과 Children
속성은 XAML 파일에 없습니다.
XamlPlusCode 샘플과 같은 속성 요소로 및 Children
속성을 포함 Content
할 수 있습니다.
<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 파일에 필요하지 않습니다 ?
XAML에서 Xamarin.Forms 사용하기 위해 정의된 요소는 클래스의 ContentProperty
특성에 플래그가 지정된 속성 하나를 가질 수 있습니다. 온라인 Xamarin.Forms 설명서에서 클래스를 ContentPage
조회하면 다음 특성이 표시됩니다.
[Xamarin.Forms.ContentProperty("Content")]
public class ContentPage : TemplatedPage
즉 Content
, 속성 요소 태그가 필요하지 않습니다. 시작 태그와 끝 ContentPage
태그 사이에 표시되는 모든 XML 콘텐츠는 속성에 Content
할당된 것으로 간주됩니다.
StackLayout
, Grid
AbsoluteLayout
및 RelativeLayout
모든 파생 Layout<View>
항목은 설명서에서 Xamarin.Forms 조회 Layout<T>
하는 경우 다른 ContentProperty
특성이 표시됩니다.
[Xamarin.Forms.ContentProperty("Children")]
public abstract class Layout<T> : Layout ...
이를 통해 명시적 Children
속성 요소 태그 없이 레이아웃의 콘텐츠를 컬렉션에 Children
자동으로 추가할 수 있습니다.
다른 클래스에는 ContentProperty
특성 정의도 있습니다. 예를 들어 콘텐츠 속성은 Label
.입니다 Text
. 다른 사용자에 대한 API 설명서를 확인합니다.
OnPlatform과의 플랫폼 차이점
단일 페이지 애플리케이션에서는 iOS 상태 막대를 덮어쓰지 않도록 페이지에서 속성을 설정하는 Padding
것이 일반적입니다. 코드에서 이 용도로 Device.RuntimePlatform
속성을 사용할 수 있습니다.
if (Device.RuntimePlatform == Device.iOS)
{
Padding = new Thickness(0, 20, 0, 0);
}
XAML에서 및 On
클래스를 사용하여 OnPlatform
비슷한 작업을 수행할 수도 있습니다. 먼저 페이지 위쪽에 있는 Padding
속성에 대한 속성 요소를 포함합니다.
<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
포함합니다. OnPlatform
는 제네릭 클래스입니다. 제네릭 형식 인수(이 경우 Thickness
속성 형식 Padding
)를 지정해야 합니다. 다행히 XAML 특성은 특히 호출 x:TypeArguments
된 제네릭 인수를 정의합니다. 설정 중인 속성의 형식과 일치해야 합니다.
<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
에는 개체의 속성이 IList
On
있습니다Platforms
. 해당 속성에 속성 요소 태그를 사용합니다.
<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
합니다. 각 속성에 Platform
대해 속성 및 속성에 Value
대한 태그를 설정할 속성은 다음과 같습니다 Thickness
.
<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>
이 태그는 간소화할 수 있습니다. 콘텐츠 속성 OnPlatform
은 Platforms
다음과 같습니다. 따라서 이러한 속성 요소 태그를 제거할 수 있습니다.
<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>
속성 On
은 Platform
형식IList<string>
이므로 값이 같으면 여러 플랫폼을 포함할 수 있습니다.
<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
으로 설정되므로 해당 태그를 제거할 수 있습니다.
<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
속성을 설정하는 표준 방법입니다. Value
설정을 단일 문자열로 나타낼 수 없는 경우 해당 설정에 대한 속성 요소를 정의할 수 있습니다.
<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 모양을 사용자 지정할 수도 있습니다. 클래스와 On
동일한 기능을 OnPlatform
제공하지만 보다 간결한 표현을 제공합니다. 자세한 내용은 OnPlatform 태그 확장을 참조 하세요.
요약
속성 요소 및 연결된 속성을 사용하여 대부분의 기본 XAML 구문이 설정되었습니다. 그러나 리소스 사전과 같이 간접적인 방식으로 속성을 개체로 설정해야 하는 경우도 있습니다. 이 방법은 다음 부분인 3부 에서 다룹니다. XAML 태그 확장입니다.