UWP 개발, 화면을 개발하는 XAML 언어 이해하기

유니버설 Windows 플랫폼(UWP)은 Microsoft가 만든 플랫폼으로, Windows 10 및 그 이후의 운영 체제에서 실행되는 애플리케이션을 개발할 수 있습니다. UWP 애플리케이션은 다양한 장치에서 공통된 사용자 경험을 제공하는 데 초점을 맞추고 있습니다. 그 중에서도 XAML(Extensible Application Markup Language)은 UWP 애플리케이션의 UI를 정의하는 데 사용되는 필수적인 언어입니다. 이번 글에서는 XAML의 기본 개념과 특징, 그리고 어떻게 UWP 애플리케이션의 화면을 구현하는 데 활용할 수 있는지 살펴보겠습니다.

XAML의 기본 개념

XAML은 XML 기반의 마크업 언어로, UI 요소와 속성을 선언적으로 정의하는 데 사용됩니다. XAML을 사용함으로써 개발자는 UI를 직관적으로 설계할 수 있으며, 코드 뒤에서 UI와 관련된 로직을 C# 또는 VB.NET과 같은 언어로 작성할 수 있습니다. 이러한 구조는 개발자와 디자이너 간의 협업을 용이하게 만들어, 역할 분담이 효과적으로 이루어질 수 있게 합니다.

XAML의 기본 구문

XAML의 기본 구조는 다음과 같습니다:

<Page x:Class="YourApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:YourApp">
    <Grid>
        <TextBlock Text="Hello, World!" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
</Page>

위 코드에서 주요 요소를 살펴보면:

  • Page: XAML 문서의 루트 요소로, 페이지를 나타냅니다.
  • x:Class: 현재 XAML 파일과 연결된 코드 비하인드 클래스의 이름을 지정합니다.
  • xmlns: XML 네임스페이스를 정의하여 XAML에서 사용할 수 있는 요소와 속성을 구분합니다.
  • Grid: UI 요소를 배치하기 위한 레이아웃 컨테이너입니다.
  • TextBlock: 텍스트를 표시하는 UI 요소로, 다양한 속성을 통해 사용자 경험을 향상시킬 수 있습니다.

속성 및 이벤트

XAML에서 UI 요소는 속성(attribute)을 통해 스타일과 동작을 정의합니다. 일반적으로 XAML의 속성은 점 형식으로 부여되며, 예를 들어 TextBlock의 텍스트를 변경하려면 다음과 같이 작성합니다:

<TextBlock Text="Hello, World!" Foreground="Blue" FontSize="24" />

이 외에도 XAML은 이벤트 핸들링을 지원합니다. 예를 들어, 버튼을 클릭했을 때 수행할 작업을 정의하고자 할 때는 다음과 같이 작성할 수 있습니다:

<Button Content="Click Me!" Click="Button_Click" />

위 코드는 “Click Me!”라는 버튼을 생성하며, 버튼 클릭 시 Button_Click이라는 이벤트 핸들러를 호출합니다.

XAML의 레이아웃 및 위젯

XAML은 다양한 레이아웃 컨테이너를 제공하여 UI 요소의 배치를 쉽게 할 수 있도록 돕습니다. 가장 일반적인 레이아웃 컨테이너로는 Grid, StackPanel, WrapPanel, RelativePanel, Canvas 등이 있습니다.

Grid

Grid는 가장 유연하고 강력한 레이아웃 컨테이너입니다. 열과 행을 정의하여 복잡한 레이아웃을 구현할 수 있습니다. 다음은 Grid를 사용하는 간단한 예입니다:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="200" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <TextBlock Grid.Row="0" Grid.Column="0" Text="Header" />
    <Button Grid.Row="1" Grid.Column="0" Content="Button 1" />
    <Button Grid.Row="1" Grid.Column="1" Content="Button 2" />
</Grid>

위의 예시에서 Grid는 두 개의 행과 두 개의 열로 구성됩니다. 첫 번째 행은 동적 크기로 설정되어 있으며, 두 번째 행은 버튼 두 개를 포함하고 있습니다.

StackPanel

StackPanel은 자식 요소들을 수평 또는 수직으로 쌓는 레이아웃 컨테이너입니다. 일반적으로 단순한 리스트를 나열할 때 유용합니다. 수직 스택 예:

<StackPanel Orientation="Vertical">
    <TextBlock Text="Item 1" />
    <TextBlock Text="Item 2" />
    <Button Content="Click Me!" />
</StackPanel>

그 외의 레이아웃

WrapPanel은 자식 요소를 자동으로 다음 줄로 넘겨주는 패널이며, RelativePanel은 UI 요소 간의 상대적인 위치를 설정할 수 있습니다. 각각의 레이아웃 컨테이너는 특정 UI 요구에 따라 선택할 수 있습니다.

데이터 바인딩과 MVVM 패턴

XAML의 또 다른 중요한 기능은 데이터 바인딩입니다. 데이터 바인딩을 통해 UI 요소와 데이터 소스 간의 연결을 설정할 수 있어, UI가 데이터에 의존하여 동적으로 변할 수 있습니다. MVVM (Model-View-ViewModel) 패턴을 활용하여 데이터를 효과적으로 관리할 수 있습니다.

간단한 데이터 바인딩 예제

다음은 XAML에서 간단한 데이터 바인딩을 사용하는 예제입니다:

<Page x:Class="YourApp.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.DataContext>
        <local:MyViewModel />
    </Page.DataContext>

    <StackPanel>
        <TextBlock Text="{Binding Title}" FontSize="32" />
        <Button Content="Update Title" Command="{Binding UpdateTitleCommand}" />
    </StackPanel>
</Page>

위 코드에서 MyViewModel 클래스가 데이터 컨텍스트로 설정되어 있고, TextBlock의 Text 속성은 그 데이터 컨텍스트의 Title 속성과 바인딩되고 있습니다.

ViewModel 예제

ViewModel 클래스는 다음과 같이 작성할 수 있습니다:

public class MyViewModel : INotifyPropertyChanged
{
    private string _title = "초기 제목";
    public string Title
    {
        get => _title;
        set
        {
            if (_title != value)
            {
                _title = value;
                OnPropertyChanged(nameof(Title));
            }
        }
    }

    public ICommand UpdateTitleCommand { get; }

    public MyViewModel()
    {
        UpdateTitleCommand = new RelayCommand(UpdateTitle);
    }

    private void UpdateTitle()
    {
        Title = "제목이 업데이트되었습니다!";
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

스타일과 템플릿

XAML에서는 스타일과 템플릿을 사용하여 UI 요소의 형식을 일관되게 유지할 수 있습니다. 이를 통해 코드의 중복을 줄이고, UI 기반의 애플리케이션을 더욱 매력적으로 만들 수 있습니다.

스타일 예제

스타일을 사용하여 TextBlock의 공통 특성을 정의할 수 있습니다:

<Page.Resources>
    <Style x:Key="MyTextBlockStyle" TargetType="TextBlock">
        <Setter Property="FontSize" Value="24" />
        <Setter Property="Foreground" Value="Green" />
    </Style>
</Page.Resources>

<TextBlock Style="{StaticResource MyTextBlockStyle}" Text="스타일이 적용된 텍스트" />

스타일은 UI 요소에 대한 시각적 속성을 일관되게 적용하는 데 큰 도움이 됩니다.

템플릿

템플릿은 UI 요소의 시각적 구조를 재정의하는 데 사용됩니다. 다음은 Button의 기본 스타일을 변경하는 예제입니다:

<Style TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border Background="{TemplateBinding Background}" Padding="10">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                </Border>
            </ControlTemplate>
        <Setter.Value>
    </Setter>
</Style>

애니메이션과 트랜지션

XAML에서는 사용자 경험을 향상시키기 위해 애니메이션과 트랜지션을 쉽게 적용할 수 있습니다. 이를 통해 애플리케이션의 상호작용이 더욱 매력적이고 직관적으로 느껴질 수 있습니다.

애니메이션 예제

다음은 간단한 크기 변화를 적용하는 애니메이션의 예입니다:

<Button Content="애니메이션 버튼" Width="100" Height="100">
    <Button.RenderTransform>
        <ScaleTransform x:Name="buttonScale" />
    </Button.RenderTransform>
    <Button.Triggers>
        <EventTrigger RoutedEvent="Button.PointerEntered">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="buttonScale" Storyboard.TargetProperty="ScaleX" To="1.2" Duration="0:0:0.2"/>
                    <DoubleAnimation Storyboard.TargetName="buttonScale" Storyboard.TargetProperty="ScaleY" To="1.2" Duration="0:0:0.2"/>
                </Storyboard>
            <BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="Button.PointerExited">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="buttonScale" Storyboard.TargetProperty="ScaleX" To="1.0" Duration="0:0:0.2"/>
                    <DoubleAnimation Storyboard.TargetName="buttonScale" Storyboard.TargetProperty="ScaleY" To="1.0" Duration="0:0:0.2"/>
                </Storyboard>
            <BeginStoryboard>
        </EventTrigger>
    </Button.Triggers>
</Button>

위 코드는 마우스가 버튼 위에 올려졌을 때 버튼의 크기를 키우고, 마우스가 벗어날 때 원래 크기로 돌아오도록 설정합니다.

마무리

XAML은 UWP 애플리케이션에서 UI 요소를 정의하고 조작하는 데 매우 강력한 도구입니다. 데이터 바인딩, 스타일 및 애니메이션과 같은 기능들을 통해 개발자는 일관된 사용자 경험을 제공할 수 있으며, UI 특성에 대한 더 큰 유연성을 구현할 수 있습니다. UWP 개발을 시작하는 데 있어 XAML의 이해는 매우 중요하며, 실습을 통해 점차 그 사용을 익히는 것이 필요합니다. 이 글이 UWP 개발과 XAML 언어에 대한 이해를 높이는 데 도움이 되길 바랍니다.

앞으로도 UWP 개발 관련 다양한 주제를 다룰 예정이니 많은 관심 바랍니다. 궁금한 점이 있으면 댓글로 남겨 주세요!

© 2023 UWP 개발 강좌 블로그