C#을 사용하여 XAML 컨트롤 빌드

이 문서에서는 C#을 사용하여 WinUI 3용 템플릿 기반 XAML 컨트롤을 만드는 과정을 안내합니다. 템플릿 기반 컨트롤은 Microsoft.UI.Xaml.Controls.Control에서 상속되며, XAML 컨트롤 템플릿을 사용하여 사용자 지정할 수 있는 시각적 구조와 시각적 동작을 포함합니다.

C# 및 C++/WinRT 앱 모두에서 사용할 수 있도록 C#에서 독립 실행형 WinUI 3 구성 요소를 만들려면 연습: WinUI 3 컨트롤을 사용하여 C# 구성 요소 만들기 및 C++ Windows 앱 SDK 애플리케이션에서 사용 문서를 참조하세요.

전제 조건

  1. 개발 환경 설정 - Windows 앱 SDK용 도구 설치를 참조하세요.
  2. 첫 번째 WinUI 3 프로젝트를 만드는 방법에 대한 지침을 따릅니다.

비어 있는 앱(BgLabelControlApp) 만들기

먼저 Microsoft Visual Studio에서 새 프로젝트를 만듭니다. 새 프로젝트 만들기 대화 상자에서 빈 앱 패키지(데스크톱의 WinUI 3) 프로젝트 템플릿을 선택하고 C++ 언어 버전을 선택해야 합니다. 파일 이름이 아래 예제의 코드와 일치하도록 프로젝트 이름을 "BgLabelControlApp"으로 설정합니다.

Blank App Project Template

앱에 템플릿 기반 컨트롤 추가

템플릿 기반 컨트롤을 추가하려면 도구 모음에서 프로젝트 메뉴를 클릭하거나 솔루션 탐색기에서 마우스 오른쪽 단추로 프로젝트를 클릭하고, 새 항목 추가를 선택합니다. Visual C#->WinUI 아래에서 사용자 지정 컨트롤(WinUI 3) 템플릿을 선택합니다. 새 컨트롤의 이름을 "BgLabelControl"로 지정하고, 추가를 클릭합니다.

사용자 지정 컨트롤 C# 파일 업데이트

C# 파일 BgLabelControl.cs에서 생성자는 컨트롤의 DefaultStyleKey 속성을 정의합니다. 컨트롤 소비자에서 템플릿을 명시적으로 지정하지 않을 경우 이 키는 사용되는 기본 템플릿을 식별합니다. 키 값은 컨트롤의 형식입니다. 나중에 제네릭 템플릿 파일을 구현할 때 이 키를 사용하는 것을 볼 수 있습니다.

public BgLabelControl()
{
    this.DefaultStyleKey = typeof(BgLabelControl);
}

템플릿 기반 컨트롤에는 코드, XAML 또는 데이터 바인딩을 통해 프로그래밍 방식으로 설정할 수 있는 텍스트 레이블이 있습니다. 시스템에서 컨트롤 레이블의 텍스트를 최신 상태로 유지하려면 DependencyPropety로 구현해야 합니다. 이렇게 하려면 먼저 문자열 속성을 선언하고, Label이라고 합니다. 지원 변수를 사용하는 대신 GetValueSetValue를 호출하여 종속성 속성의 값을 설정하고 가져옵니다. 이러한 메서드는 Microsoft.UI.Xaml.Controls.Control에서 상속하는 DependencyObject에서 제공합니다.

public string Label
{
    get => (string)GetValue(LabelProperty);
    set => SetValue(LabelProperty, value);
}

그런 다음, 종속성 속성을 선언하고, DependencyProperty.Register를 호출하여 시스템에 등록합니다. 이 메서드는 Label 속성의 이름과 형식, 속성 소유자의 형식, BgLabelControl 클래스 및 속성의 기본값을 지정합니다.

DependencyProperty LabelProperty = DependencyProperty.Register(
    nameof(Label), 
    typeof(string),
    typeof(BgLabelControl), 
    new PropertyMetadata(default(string), new PropertyChangedCallback(OnLabelChanged)));

이러한 두 단계는 종속성 속성을 구현하는 데 필요한 모든 것이지만, 다음 예제에서는 OnLabelChanged 이벤트에 대한 선택적 처리기를 추가합니다. 속성 값이 업데이트될 때마다 시스템에서 이 이벤트가 발생합니다. 이 경우 새 레이블 텍스트가 빈 문자열인지 확인하고, 이에 따라 클래스 변수를 업데이트합니다.

public bool HasLabelValue { get; set; }

private static void OnLabelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    BgLabelControl labelControl = d as BgLabelControl; //null checks omitted
    String s = e.NewValue as String; //null checks omitted
    if (s == String.Empty)
    {
        labelControl.HasLabelValue = false;
    }
    else
    {
        labelControl.HasLabelValue = true;
    }
}

종속성 속성의 작동 방식에 대한 자세한 내용은 종속성 속성 개요를 참조하세요.

BgLabelControl의 기본 스타일 정의

컨트롤 사용자가 스타일을 명시적으로 설정하지 않은 경우 템플릿 기반 컨트롤에서 사용되는 기본 스타일 템플릿을 제공해야 합니다. 이 단계에서는 컨트롤의 제네릭 템플릿 파일을 만듭니다.

앱에 사용자 지정 컨트롤(WinUI)을 추가하면 제네릭 템플릿 파일이 생성됩니다. 이 파일의 이름은 "Generic.xaml"이며 솔루션 탐색기의 Themes 폴더에 생성됩니다. XAML 프레임워크에서 템플릿 기반 컨트롤의 기본 스타일을 찾으려면 폴더 이름과 파일 이름이 필요합니다. Generic.xaml의 기본 내용을 삭제하고, 아래 태그를 붙여넣습니다.

<!-- \Themes\Generic.xaml -->
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:BgLabelControlApp">

    <Style TargetType="local:BgLabelControl" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:BgLabelControl">
                    <Grid Width="100" Height="100" Background="{TemplateBinding Background}">
                        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{TemplateBinding Label}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

이 예제에서는 Style 요소의 TargetType 특성이 BgLabelControlApp 네임스페이스 내에서 BgLabelControl 형식으로 설정되어 있음을 확인할 수 있습니다. 이 형식은 컨트롤의 기본 스타일로 식별하는 컨트롤 생성자의 DefaultStyleKey 속성에 대해 위에서 지정한 것과 동일한 값입니다.

컨트롤 템플릿에 있는 TextBlockText 속성은 컨트롤의 Label 종속성 속성과 바인딩됩니다. 이 속성은 TemplateBinding 태그 확장을 사용하여 바인딩됩니다. 또한 이 예제에서는 Grid 배경을 Control 클래스에서 상속된 Background 종속성 속성에 바인딩합니다.

주 UI 페이지에 BgLabelControl 인스턴스 추가

MainWindow.xaml을 엽니다. 여기에는 기본 UI 페이지에 사용할 XAML 태그가 포함되어 있습니다. StackPanel 내부에서 Button 요소 바로 뒤에 다음 태그를 추가합니다.

<local:BgLabelControl Background="Red" Label="Hello, World!"/>

앱을 만들고 실행하면 지정된 배경색과 레이블이 있는 템플릿 기반 컨트롤이 표시됩니다.

Templated control result

참고 항목