다음을 통해 공유


Xamarin.Forms 리소스 사전

A ResourceDictionary 는 애플리케이션에서 사용하는 리소스에 대한 리포지토리입니다 Xamarin.Forms . 포함 스타일, 컨트롤 템플릿, 데이터 템플릿, 색 및 변환기에서 저장 ResourceDictionary 되는 일반적인 리소스입니다.

XAML에서 A에 ResourceDictionary 저장된 리소스는 참조하거나 태그 확장을 사용하여 StaticResource DynamicResource 요소에 적용할 수 있습니다. C#에서는 문자열 기반 인덱서를 사용하여 리소스를 ResourceDictionary 정의한 다음 요소에 참조 및 적용할 수도 있습니다. 그러나 공유 개체를 필드 또는 속성으로 저장하고 사전에서 먼저 검색하지 않고도 직접 액세스할 수 있으므로 C#에서 사용하는 ResourceDictionary 것은 거의 이점이 없습니다.

XAML에서 리소스 만들기

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

Xamarin.Forms 애플리케이션은 파생되는 Application클래스만 포함하지만 페이지, 레이아웃 및 컨트롤을 포함하여 파생VisualElement되는 많은 클래스를 사용하는 경우가 많습니다. 이러한 개체는 해당 Resources 속성을 포함하는 리소스로 ResourceDictionary 설정할 수 있습니다. 리소스를 사용할 수 있는 특정 ResourceDictionary 영향을 넣을 위치 선택:

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

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

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

<Application xmlns="http://xamarin.com/schemas/2014/forms"
             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>

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

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

    </Application.Resources>
</Application>

이 예제에서 리소스 사전은 Thickness 리소스, 여러 Color 리소스 및 두 개의 암시적 Style 리소스를 정의합니다. 클래스에 대한 자세한 내용은 App Class를 App 참조 Xamarin.Forms 하세요.

참고 항목

명시적 ResourceDictionary 태그 사이에 모든 리소스를 배치하는 것도 유효합니다. 그러나 3.0이므로 Xamarin.Forms 태그는 ResourceDictionary 필요하지 않습니다. 대신 개체가 ResourceDictionary 자동으로 만들어지고 속성 요소 태그 사이에 리소스를 직접 삽입할 Resources 수 있습니다.

XAML에서 리소스 사용

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

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

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

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ResourceDictionaryDemo.HomePage"
             Title="Home Page">
    <StackLayout Margin="{StaticResource PageMargin}">
        <StackLayout.Resources>
            <!-- Implicit style -->
            <Style TargetType="Button">
                <Setter Property="FontSize" Value="Medium" />
                <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 암시적 스타일을 사용합니다. 이로 인해 결국 다음 스크린샷에 표시된 모양이 됩니다.

ResourceDictionary 리소스 사용

Important

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

리소스 조회 동작

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

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

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

리소스 재정의

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

독립 실행형 리소스 사전

파생된 클래스는 ResourceDictionary 독립 실행형 XAML 파일에 있을 수도 있습니다. 그런 다음 XAML 파일을 애플리케이션 간에 공유할 수 있습니다.

이러한 파일을 만들려면 프로젝트에 새 콘텐츠 보기 또는 콘텐츠 페이지 항목을 추가합니다(C# 파일만 있는 콘텐츠 보기 또는 콘텐츠 페이지는 추가하지 않음). 코드 숨김 파일을 삭제하고 XAML 파일에서 기본 클래스 ContentView 의 이름을 변경합니다 ContentPage ResourceDictionary. 또한 파일의 x:Class 루트 태그에서 특성을 제거합니다.

다음 XAML 예제에서는 MyResourceDictionary.xaml이라는 이름을 보여 ResourceDictionary 줍니다.

<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <DataTemplate x:Key="PersonDataTemplate">
        <ViewCell>
            <Grid>
                <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 은 다른 리소스 사전으로 병합하여 사용할 수 있습니다.

기본적으로 링커는 링커 동작이 모든 어셈블리를 연결하도록 설정된 경우 릴리스 빌드에서 독립 실행형 XAML 파일을 제거합니다. 독립 실행형 XAML 파일이 릴리스 빌드에 유지되도록 하려면 다음을 수행합니다.

  1. 독립 실행형 XAML 파일을 포함하는 어셈블리에 사용자 지정 Preserve 특성을 추가합니다. 자세한 내용은 코드 유지를 참조 하세요.

  2. Preserve 어셈블리 수준에서 특성을 설정합니다.

    [assembly:Preserve(AllMembers = true)]
    

연결에 대한 자세한 내용은 Xamarin.iOS 앱 연결 및 Android에서 연결을 참조하세요.

병합된 리소스 사전

병합된 리소스 사전은 하나 이상의 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

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

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

A를 ResourceDictionary 다른 속성에 추가하여 다른 ResourceDictionary A로 MergedDictionaries ResourceDictionary병합할 수도 있습니다. 이 기술을 사용하면 리소스 사전이 있는 어셈블리에 관계없이 리소스 사전을 병합할 수 있습니다. 외부 어셈블리에서 리소스 사전을 병합하려면 ResourceDictionary 빌드 작업을 EmbeddedResource설정하고, 코드 숨김 파일을 갖고, 파일의 루트 태그에 특성을 정의 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:LightTheme />
                <!-- Add more resource dictionaries here -->
            </ResourceDictionary.MergedDictionaries>
            <!-- Add more resources here -->
        </ResourceDictionary>
    </ContentPage.Resources>
    ...
</ContentPage>

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

Important

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

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

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

참고 항목

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

Channel 9YouTube에서 더 많은 Xamarin 비디오를 확인하세요.