다음을 통해 공유


리소스 사전

.NET 다중 플랫폼 앱 UI(.NET MAUI) ResourceDictionary 는 .NET MAUI 앱에서 사용하는 리소스에 대한 리포지토리입니다. 포함 스타일, 컨트롤 템플릿, 데이터 템플릿, 변환기 및 색에 저장 ResourceDictionary 되는 일반적인 리소스입니다.

A에 ResourceDictionary 저장된 XAML 리소스는 참조하거나 태그 확장을 사용하여 StaticResource DynamicResource 요소에 적용할 수 있습니다. C#에서는 문자열 기반 인덱서를 사용하여 리소스를 ResourceDictionary 정의한 다음 요소에 참조 및 적용할 수도 있습니다.

Visual Studio에서 코드 숨김 파일로 지원되는 XAML 기반 ResourceDictionary 파일은 .NET MAUI ResourceDictionary(XAML) 항목 템플릿을 통해 프로젝트에 추가할 수 있습니다.

리소스 만들기

모든 VisualElement 파생 개체에는 리소스를 Resources 포함할 수 있는 ResourceDictionary 속성이 있습니다. 마찬가지로 파생 Application 개체에는 리소스를 Resources 포함할 수 있는 ResourceDictionary 속성이 있습니다.

.NET MAUI 앱은 파생되는 Application단일 클래스만 포함할 수 있지만 페이지, 레이아웃 및 보기를 포함하여 파생 VisualElement되는 많은 클래스를 사용하는 경우가 많습니다. 이러한 개체는 해당 Resources 속성을 포함하는 리소스로 ResourceDictionary 설정할 수 있습니다. 리소스를 사용할 수 있는 특정 ResourceDictionary 영향을 넣을 위치 선택:

  • 뷰에 ResourceDictionary 연결된 리소스(예: Button 또는 Label)는 해당 특정 개체에만 적용할 수 있습니다.
  • 레이아웃에 ResourceDictionary 연결된 리소스(예: StackLayout 또는 Grid)를 레이아웃 및 해당 레이아웃의 모든 자식에 적용할 수 있습니다.
  • ResourceDictionary 페이지 수준에서 정의된 리소스는 페이지 및 모든 자식에 적용할 수 있습니다.
  • ResourceDictionary 애플리케이션 수준에서 정의된 리소스는 앱 전체에 적용할 수 있습니다.

암시적 스타일을 제외하고 리소스 사전의 각 리소스에는 특성으로 x:Key 정의된 고유한 문자열 키가 있어야 합니다.

다음 XAML은 App.xaml 파일의 애플리케이션 수준에 ResourceDictionary 정의된 리소스를 보여 줍니다.

<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ResourceDictionaryDemo.App">
    <Application.Resources>

        <Thickness x:Key="PageMargin">20</Thickness>

        <!-- Colors -->
        <Color x:Key="AppBackgroundColor">AliceBlue</Color>
        <Color x:Key="NavigationBarColor">#1976D2</Color>
        <Color x:Key="NavigationBarTextColor">White</Color>
        <Color x:Key="NormalTextColor">Black</Color>

        <!-- Images -->
        <x:String x:Key="BackgroundImage">background</x:String>
        <x:String x:Key="MenuIcon">menu.png</x:String>
        <x:String x:Key="SearchIcon">search.png</x:String>

        <!-- Implicit styles -->
        <Style TargetType="NavigationPage">
            <Setter Property="BarBackgroundColor"
                    Value="{StaticResource NavigationBarColor}" />
            <Setter Property="BarTextColor"
                    Value="{StaticResource NavigationBarTextColor}" />
        </Style>

        <Style TargetType="ContentPage"
               ApplyToDerivedTypes="True">
            <Setter Property="BackgroundColor"
                    Value="{StaticResource AppBackgroundColor}" />
        </Style>

    </Application.Resources>
</Application>

이 예제에서 리소스 사전은 Thickness 리소스, 여러 Color 리소스 및 두 개의 암시적 Style 리소스를 정의합니다.

Important

속성 요소 태그 사이에 직접 리소스를 Resources 삽입하면 개체가 ResourceDictionary 자동으로 만들어집니다. 그러나 선택적 ResourceDictionary 태그 사이에 모든 리소스를 배치하는 것도 유효합니다.

리소스 사용

각 리소스에는 특성을 사용하여 x:Key 지정된 키가 있으며, 이 키는 해당 사전 키가 ResourceDictionary됩니다. 키는 또는 DynamicResource XAML 태그 확장에서 ResourceDictionary 리소스를 StaticResource 참조하는 데 사용됩니다.

태그 확장은 StaticResource 모두 사전 키를 사용하여 리소스 사전의 값을 참조한다는 측면에서 태그 확장과 유사 DynamicResource 합니다. 그러나 태그 확장이 StaticResource 단일 사전 조회를 수행하는 동안 태그 확장은 DynamicResource 사전 키에 대한 링크를 유지 관리합니다. 따라서 키와 연결된 사전 항목이 바뀌면 변경 내용이 시각적 요소에 적용됩니다. 이렇게 하면 앱에서 런타임 리소스를 변경할 수 있습니다. 태그 확장에 대한 자세한 내용은 XAML 태그 확장을 참조 하세요.

다음 XAML 예제에서는 리소스를 사용하고 다음에서 StackLayout추가 리소스를 정의하는 방법을 보여 줍니다.

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ResourceDictionaryDemo.MainPage"
             Title="Main page">
    <StackLayout Margin="{StaticResource PageMargin}"
                 Spacing="6">
        <StackLayout.Resources>
            <!-- Implicit style -->
            <Style TargetType="Button">
                <Setter Property="FontSize" Value="14" />
                <Setter Property="BackgroundColor" Value="#1976D2" />
                <Setter Property="TextColor" Value="White" />
                <Setter Property="CornerRadius" Value="5" />
            </Style>
        </StackLayout.Resources>

        <Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries." />
        <Button Text="Navigate"
                Clicked="OnNavigateButtonClicked" />
    </StackLayout>
</ContentPage>

이 예제에서 개체는 ContentPage 애플리케이션 수준 리소스 사전에 정의된 암시적 스타일을 사용합니다. 개체는 StackLayout 애플리케이션 수준 리소스 사전에 정의된 리소스를 사용하는 PageMargin 반면 Button , 개체는 리소스 사전에 정의된 StackLayout 암시적 스타일을 사용합니다. 그러면 다음 스크린샷에 표시된 모양이 표시됩니다.

리소스 사전 리소스 사용.

Important

단일 페이지와 관련된 리소스는 애플리케이션 수준 리소스 사전에 포함되어서는 안 됩니다. 이러한 리소스는 페이지에서 필요한 경우 대신 앱 시작 시 구문 분석됩니다. 자세한 내용은 애플리케이션 리소스 사전 크기 줄이기를 참조하세요.

리소스 조회 동작

다음 조회 프로세스는 리소스가 또는 DynamicResource 태그 확장으로 StaticResource 참조될 때 발생합니다.

  • 요청된 키가 있는 경우 리소스 사전에서 속성을 설정하는 요소에 대해 확인합니다. 요청된 키를 찾으면 해당 값이 반환되고 조회 프로세스가 종료됩니다.
  • 일치하는 항목을 찾을 수 없는 경우 조회 프로세스는 시각적 트리를 위쪽으로 검색하여 각 부모 요소의 리소스 사전을 확인합니다. 요청된 키를 찾으면 해당 값이 반환되고 조회 프로세스가 종료됩니다. 그렇지 않으면 루트 요소에 도달할 때까지 프로세스가 위쪽으로 계속됩니다.
  • 루트 요소에서 일치 항목을 찾을 수 없는 경우 애플리케이션 수준 리소스 사전이 검사됩니다.
  • 일치 항목을 아직 찾을 수 없으면 throw XamlParseException 됩니다.

따라서 XAML 파서 StaticResource DynamicResource 가 검색된 첫 번째 일치 항목을 사용하여 시각적 트리를 통해 이동하여 일치하는 키를 검색합니다. 이 검색이 페이지에서 끝나고 키를 아직 찾을 수 없는 경우 XAML 파서는 개체에 ResourceDictionary 연결된 검색을 App 검색합니다. 키를 아직 찾을 수 없으면 예외가 throw됩니다.

리소스 재정의

리소스가 키를 공유하는 경우 시각적 트리에서 더 낮은 리소스가 정의된 리소스보다 우선합니다. 예를 들어 애플리케이션 수준에서 리소스를 AppBackgroundColor AliceBlue 설정하는 것은 페이지 수준 AppBackgroundColor 리소스를 로 설정하여 Teal재정의됩니다. 마찬가지로 페이지 수준 리소스는 레이아웃 또는 뷰 수준 AppBackgroundColor AppBackgroundColor 리소스에 의해 재정의됩니다.

독립 실행형 리소스 사전

A는 ResourceDictionary 코드 숨김 파일에서 지원되지 않는 독립 실행형 XAML 파일로 만들 수도 있습니다. 독립 실행형 ResourceDictionary파일을 만들려면 .NET MAUI ResourceDictionary(XAML) 항목 템플릿을 사용하여 프로젝트에 새 ResourceDictionary 파일을 추가하고 코드 숨김 파일을 삭제합니다. 그런 다음 XAML 파일에서 파일 시작 근처의 태그에서 ResourceDictionary 특성을 제거 x:Class 합니다. 또한 XAML이 컴파일되도록 XML 헤더 뒤를 추가 <?xaml-comp compile="true" ?> 합니다.

A는 ResourceDictionary 코드 숨김 파일에서 지원되지 않는 독립 실행형 XAML 파일로 만들 수도 있습니다. 독립 실행형 ResourceDictionary파일을 만들려면 .NET MAUI ResourceDictionary(XAML) 항목 템플릿을 사용하여 프로젝트에 새 ResourceDictionary 파일을 추가하고 코드 숨김 파일을 삭제합니다. 그런 다음 XAML 파일에서 파일 시작 근처의 태그에서 ResourceDictionary 특성을 제거 x:Class 합니다. 기본적으로 독립 실행형 ResourceDictionary 에는 XML 헤더 다음에 지정되지 않는 한 <?xaml-comp compile="false" ?> XAML이 컴파일됩니다.

참고 항목

독립 실행형 ResourceDictionary 에는 MauiXaml빌드 동작이 있어야 합니다.

다음 XAML 예제에서는 MyResourceDictionary.xaml이라는 독립 실행형 ResourceDictionary 을 보여 줍니다.

<?xml version="1.0" encoding="UTF-8" ?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <DataTemplate x:Key="PersonDataTemplate">
        <ViewCell>
            <Grid RowSpacing="6"
                  ColumnSpacing="6">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0.5*" />
                    <ColumnDefinition Width="0.2*" />
                    <ColumnDefinition Width="0.3*" />
                </Grid.ColumnDefinitions>
                <Label Text="{Binding Name}"
                       TextColor="{StaticResource NormalTextColor}"
                       FontAttributes="Bold" />
                <Label Grid.Column="1"
                       Text="{Binding Age}"
                       TextColor="{StaticResource NormalTextColor}" />
                <Label Grid.Column="2"
                       Text="{Binding Location}"
                       TextColor="{StaticResource NormalTextColor}"
                       HorizontalTextAlignment="End" />
            </Grid>
        </ViewCell>
    </DataTemplate>
</ResourceDictionary>

이 예제에서는 형식DataTemplateResourceDictionary 개체인 단일 리소스를 포함합니다. MyResourceDictionary.xaml 은 다른 리소스 사전으로 병합하여 사용할 수 있습니다.

리소스 사전 병합

리소스 사전은 하나 이상의 ResourceDictionary 개체를 다른 ResourceDictionary개체로 병합하여 결합할 수 있습니다.

로컬 리소스 사전 병합

리소스가 있는 XAML 파일의 파일 이름으로 속성이 Source 설정된 개체를 만들어 ResourceDictionary 로컬 ResourceDictionary 파일을 다른 ResourceDictionary 파일로 병합할 수 있습니다.

<ContentPage ...>
    <ContentPage.Resources>
        <!-- Add more resources here -->
        <ResourceDictionary Source="MyResourceDictionary.xaml" />
        <!-- Add more resources here -->
    </ContentPage.Resources>
    ...
</ContentPage>

이 구문은 클래스를 MyResourceDictionary 인스턴스화하지 않습니다. 대신 XAML 파일을 참조합니다. 따라서 속성을 설정할 Source 때 코드 숨김 파일이 필요하지 x:Class 않으며 MyResourceDictionary.xaml 파일의 루트 태그에서 특성을 제거할 수 있습니다.

Important

이 속성은 ResourceDictionary.Source XAML에서만 설정할 수 있습니다.

다른 어셈블리에서 리소스 사전 병합

A를 ResourceDictionary 다른 속성에 추가하여 다른 ResourceDictionary A로 MergedDictionaries ResourceDictionary병합할 수도 있습니다. 이 기술을 사용하면 리소스 사전이 있는 어셈블리에 관계없이 리소스 사전을 병합할 수 있습니다. 외부 어셈블리에서 리소스 사전을 병합하려면 ResourceDictionary 빌드 작업을 MauiXaml설정하고, 코드 숨김 파일을 갖고, 파일의 루트 태그에 특성을 정의 x:Class 해야 합니다.

Warning

또한 ResourceDictionary 클래스는 MergedWith 속성을 정의합니다. 그러나 이 속성은 더 이상 사용되지 않으며 더 이상 사용되지 않아야 합니다.

다음 코드 예제에서는 페이지 수준의 ResourceDictionary컬렉션에 MergedDictionaries 추가되는 두 개의 리소스 사전을 보여줍니다.

<ContentPage ...
             xmlns:local="clr-namespace:ResourceDictionaryDemo"
             xmlns:theme="clr-namespace:MyThemes;assembly=MyThemes">
    <ContentPage.Resources>
        <ResourceDictionary>
            <!-- Add more resources here -->
            <ResourceDictionary.MergedDictionaries>
                <!-- Add more resource dictionaries here -->
                <local:MyResourceDictionary />
                <theme:DefaultTheme />
                <!-- Add more resource dictionaries here -->
            </ResourceDictionary.MergedDictionaries>
            <!-- Add more resources here -->
        </ResourceDictionary>
    </ContentPage.Resources>
    ...
</ContentPage>

이 예제에서는 동일한 어셈블리의 리소스 사전과 외부 어셈블리의 리소스 사전이 페이지 수준 리소스 사전에 병합됩니다. 또한 속성 요소 태그 내의 MergedDictionaries 다른 ResourceDictionary 개체 및 해당 태그 외부의 다른 리소스를 추가할 수도 있습니다.

Important

속성 요소 태그는 ResourceDictionary하나 MergedDictionaries 만 있을 수 있지만 필요한 만큼 ResourceDictionary 개체를 배치할 수 있습니다.

병합된 ResourceDictionary 리소스가 동일한 x:Key 특성 값을 공유하는 경우 .NET MAUI는 다음 리소스 우선 순위를 사용합니다.

  1. 리소스 사전에 로컬인 리소스입니다.
  2. 컬렉션을 통해 MergedDictionaries 병합된 리소스 사전에 포함된 리소스는 역순으로 속성에 MergedDictionaries 나열됩니다.

앱에 대규모 리소스 사전이 여러 개 포함된 경우 리소스 사전 검색은 계산 집약적인 작업이 될 수 있습니다. 따라서 불필요한 검색을 방지하려면 애플리케이션의 각 페이지에서 페이지에 적합한 리소스 사전만 사용해야 합니다.

코드에서 XAML 기반 리소스 사전 사용

XAML에 정의된 리소스 사전은 코드 숨김 파일에서 지원되는 ResourceDictionary 경우 코드에서 사용할 수 있습니다. Visual Studio에서 코드 숨김 파일로 지원되는 XAML 기반 ResourceDictionary 파일은 .NET MAUI ResourceDictionary(XAML) 항목 템플릿을 통해 프로젝트에 추가할 수 있습니다.

코드 숨김으로 지원되는 리소스 사전의 스크린샷

코드 숨김 파일에서 지원되는 XAML 기반 리소스 사전은 리소스 사전의 컬렉션에 추가하여 MergedDictionaries C#에서 사용할 수 있습니다.

Resources.MergedDictionaries.Add(new MyMauiApp.Resources.Styles.MyColors());
Resources.MergedDictionaries.Add(new MyMauiApp.Resources.Styles.MyStyles());

코드에서 키로 리소스 액세스

다른 사전과 같은 코드에서 리소스 사전의 리소스에 액세스할 수 있습니다.

다음 예제에서는 페이지의 리소스 사전에서 리소스를 검색하고 적용하는 방법을 보여줍니다.

// Retrieve the Primary color value which is in the page's resource dictionary
var hasValue = Resources.TryGetValue("Primary", out object primaryColor);

if (hasValue)
{
    myLabel.TextColor = (Color)primaryColor;
}

코드에서 리소스를 검색할 수 없는 경우 .NET MAUI가 throw KeyNotFoundException 되지 않도록 하는 권장 방법입니다. 이 문제는 병합된 리소스 사전이 XAML 파일 및 인라인 리소스에 정의된 리소스로 구성될 때 발생할 수 있습니다. 자세한 내용은 GitHub 문제 #11214를 참조하세요.

참고 항목

코드에서 앱 전체 리소스를 검색하려면 리소스 사전에 액세스 App.Current.Resources 합니다.