XAML 태그 확장

완료됨

대부분의 XAML 정의는 컴파일 시간에 해결됩니다. 요소를 배치해야 하는 위치, 사용할 색 및 글꼴, 속성에 할당해야 하는 리터럴 값을 알고 있는 경우가 많습니다.

그러나 속성 값을 컴파일 시간에 확인할 수 없는 값으로 설정해야 하는 경우도 있습니다. 이러한 값은 프로그램이 실행 중일 때만 알려집니다. 이러한 상황에서는 런타임에 XAML에 값을 제공하는 개체를 만들 수 있습니다. XAML은 이러한 목적으로 태그 확장을 지원합니다.

이 단원에서는 태그 확장을 만들고 사용하는 방법을 알아봅니다.

태그 확장이란?

태그 확장은 XAML에서 런타임 값에 액세스하는 데 사용되는 클래스입니다. XAML UI에 많은 레이블이 정의되어 있고 모든 레이블 스타일이 일관되도록 앱 전체에서 FontSize 속성을 동일한 값으로 설정한다고 가정해 보겠습니다. 다음 예와 같이 XAML을 사용하여 FontSize 속성을 설정할 수 있습니다.

<Label Text="Hello, World!"
            Grid.Row="0"
            SemanticProperties.HeadingLevel="Level1"
            FontSize="28"
            HorizontalOptions="CenterAndExpand"/>

모든 레이블에 대해 이 동일한 설정을 반복할 수 있지만 나중에 이 값을 변경하려면 어떻게 해야 할까요? 이 속성의 모든 인스턴스를 찾아서 변경해야 합니다. 따라서 사용해야 하는 값을 모른다고 가정합니다. 이 값은 디바이스 방향, 화면 해상도 또는 기타 고려 사항과 같은 요소에 따라 런타임에 계산될 수 있습니다. 이러한 경우 하드 코딩된 리터럴보다 더 정교한 항목이 필요합니다. 여기서는 태그 확장이 유용합니다. 태그 확장은 XAML에 사용되는 값을 획득할 수 있는 유연성을 제공합니다.

태그 확장 만들기

태그 확장은 Microsoft.Maui.Controls.Xaml.IMarkupExtension 인터페이스를 구현하는 클래스입니다. 이 인터페이스는 다음 서명을 사용하여 ProvideValue라는 하나의 메서드를 정의합니다.

public object ProvideValue(IServiceProvider serviceProvider)
{
    ...
}

이 메서드의 목적은 XAML 태그에 값을 제공하는 것입니다. 반환 형식은 object이므로 값이 사용되는 위치에 적합한 경우 값은 모든 형식이 될 수 있습니다. 예를 들어 글꼴 크기를 계산하여 반환하는 태그 확장에서 반환 형식은 double입니다.

serviceProvider 매개 변수에는 XAML 코드에서 태그 확장이 사용되는 위치에 대한 컨텍스트 정보가 포함됩니다. 다른 정보 조각 중에서 확장이 적용되는 컨트롤을 식별합니다.

FontSize 속성의 태그 확장을 단순하게 유지할 수 있습니다. 다음 예에서 MainPage 클래스는 MyFontSize라는 double 필드를 노출합니다. GlobalFontSizeExtension 클래스는 IMarkupExtension 인터페이스를 구현하고 ProvideValue 메서드는 MyFontSize 변수의 값을 반환합니다.

namespace MyMauiApp;

public partial class MainPage : ContentPage
{
    public const double MyFontSize = 28;

    public MainPage()
    {
        InitializeComponent();
        ...
    }
    ...
}

public class GlobalFontSizeExtension : IMarkupExtension
{
    public object ProvideValue(IServiceProvider serviceProvider)
    {
        return MainPage.MyFontSize;
    }
}

참고 항목

MyFontSize 필드는 MainPage 클래스의 static 멤버여야만 이런 방법으로 ProvideValue 메서드에서 참조될 수 있습니다. 모범 사례는 이 경우 변수도 상수여야 함을 의미합니다. const 값은 static입니다.

ProvideValue 메서드는 방향 및 디바이스 폼 팩터에 따라 반환되는 값을 조정할 수도 있습니다.

XAML의 컨트롤에 태그 확장 적용

XAML 코드에서 태그 확장을 사용하려면 GlobalFontSizeExtension 클래스가 포함된 네임스페이스를 ContentPage 태그의 네임스페이스 목록에 추가합니다. 다음 예제에서 이 네임스페이스에는 mycode 별칭이 지정됩니다.

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:mycode="clr-namespace:MyMauiApp"
             x:Class="MyMauiApp.MainPage">

태그 확장을 사용하여 이와 같이 FontSize 속성을 설정할 수 있습니다. 규칙에 따라 태그 확장의 이름에 Extension 접미사가 있습니다. XAML에서 이 접미사를 인식하므로 XAML 코드에서 확장을 호출할 때 이 접미사를 포함할 필요가 없습니다. 다음 예에서 GlobalFontSizeExtension 클래스는 단순히 GlobalFontSize로 참조됩니다.

<Label Text="Hello, World!"
            Grid.Row="0"
            SemanticProperties.HeadingLevel="Level1"
            FontSize="{mycode:GlobalFontSize}"
            HorizontalOptions="CenterAndExpand"/>

글꼴 크기를 지정해야 하는 모든 컨트롤에 대해 XAML 코드 전체에서 동일한 태그 확장을 적용할 수 있습니다. 나중에 글꼴 크기를 변경하기로 결정하면 MainPage 클래스의 MyFontSize 변수 정의만 수정하면 됩니다.

StaticExtension 클래스

GlobalFontSize 태그 확장이 아무리 유용하더라도 그런 확장을 직접 만들 가능성은 낮습니다. 그 이유는 간단합니다. .NET MAUI는 코드에서 정적 값을 참조할 수 있도록 하는 더 일반화된 확장을 이미 제공하고 있습니다. 이 확장명의 이름은 StaticExtension이며, 줄여서 Static이라고 합니다. 다음 코드는 이 확장 클래스의 기본 개요를 보여 줍니다.

[ContentProperty ("Member")]
public class StaticExtension : IMarkupExtension
{
    public string Member {get; set;}
    public object ProvideValue (IServiceProvider serviceProvider)
    {
        ...
    }
}

참고 항목

사용자 지정 태그 확장의 목적은 단순한 정적 사례보다는 더 복잡한 상황을 처리할 수 있도록 하는 것입니다. 예를 들어, 디바이스 폼 팩터에 따라 글꼴 크기를 동적으로 변경해야 할 수도 있습니다.

XAML 코드에서 이 클래스를 사용하려면 Member 속성에서 참조하려는 정적 변수의 이름을 제공하면 ProvideValue 메서드는 이 변수의 값을 반환합니다. 다음 예제에서는 이를 사용하는 방법을 보여 줍니다.

<Label Text="Hello, World!"
            Grid.Row="0"
            SemanticProperties.HeadingLevel="Level1"
            FontSize="{x:Static Member=mycode:MainPage.MyFontSize}"
            HorizontalOptions="CenterAndExpand"/>

.NET MAUI는 데이터 바인딩, 동적 리소스 및 스타일 참조, 데이터 배열 처리와 같은 시나리오에 사용할 수 있는 다른 태그 확장 클래스 세트를 제공합니다.

지식 점검

1.

어떤 태그 확장을 사용하면 XAML 속성을 코드 숨김 클래스에 정의되는 정적 값으로 설정할 수 있나요?

2.

사용자 지정 태그 확장을 만드는 데 사용하는 인터페이스는 무엇인가요?