Xamarin.Forms リソース ディクショナリ

Download Sample サンプルをダウンロードします

A ResourceDictionary は、アプリケーションによって使用されるリソースのリポジトリです Xamarin.Forms 。 スタイルコントロール テンプレートデータ テンプレート、色、コンバーターなど、一般的なリソースが格納されますResourceDictionary

XAML では、a に格納されているResourceDictionaryリソースを参照し、またはDynamicResourceマークアップ拡張機能を使用して要素にStaticResource適用できます。 C# では、リソースを a で定義し、文字列ベースの ResourceDictionary インデクサーを使用して要素を参照して適用することもできます。 ただし、共有オブジェクトをフィールドまたはプロパティとして格納し、最初にディクショナリから取得しなくても直接アクセスできるため、C# で使用 ResourceDictionary する利点はほとんどありません。

XAML でリソースを作成する

すべての VisualElement 派生オブジェクトには、リソースを Resources 含めることができるプロパティ ResourceDictionary があります。 同様に、 Application 派生オブジェクトには、リソースを Resources 含めることができるプロパティ ResourceDictionary があります。

Xamarin.Formsアプリケーションには、派生元Applicationのクラスのみが含まれますが、多くの場合、ページ、レイアウト、コントロールなど、派生元VisualElementの多くのクラスを使用します。 これらのオブジェクトは、そのプロパティを Resources 含むリソースに ResourceDictionary 設定できます。 リソースを使用できる場所に特定 ResourceDictionary の影響を与える場所の選択:

  • ビューにResourceDictionaryアタッチされているリソース (またはそのButtonLabel特定のオブジェクトにのみ適用できるリソース)。
  • レイアウトにResourceDictionaryアタッチされているリソース (レイアウトStackLayoutGridとそのレイアウトのすべての子など) に適用できます。
  • ページ レベルで定義された 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>

この例では、リソース ディクショナリは、リソース、複数Colorのリソース、および 2 つの暗黙的なStyleリソースを定義Thicknessします。 クラスのApp詳細については、「App Class」を参照してくださいXamarin.Forms

注意

また、すべてのリソースを明示的な ResourceDictionary タグの間に配置することも有効です。 ただし、3.0 ResourceDictionary のXamarin.Formsタグは必要ありません。 代わりに、 ResourceDictionary オブジェクトが自動的に作成され、プロパティ要素タグの間に直接リソースを Resources 挿入できます。

XAML でリソースを使用する

各リソースには、属性を x:Key 使用して指定されたキーがあり、このキー ResourceDictionaryが . キーは、拡張機能またはDynamicResourceマークアップ拡張機能を使用してリソースをStaticResourceResourceDictionary参照するために使用されます。

マークアップ拡張機能は StaticResource 、両方ともディクショナリ キーを DynamicResource 使用してリソース ディクショナリから値を参照するという点で、マークアップ拡張機能に似ています。 ただし、マークアップ拡張機能は StaticResource 1 つのディクショナリ検索を実行しますが 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 使用します。 この結果、次のスクリーンショットに示すような外観が表示されます。

Consuming ResourceDictionary Resources

重要

1 つのページに固有のリソースは、アプリケーション レベルのリソース ディクショナリに含めてはなりません。そのため、そのようなリソースは、ページで必要な場合ではなく、アプリケーションの起動時に解析されます。 詳細については、「 アプリケーション リソース ディクショナリのサイズを小さくする」を参照してください。

リソース参照の動作

次の参照プロセスは、リソースが拡張またはDynamicResourceマークアップで参照されている場合にStaticResource発生します。

  • 要求されたキーは、リソース ディクショナリが存在する場合は、プロパティを設定する要素に対してチェックされます。 要求されたキーが見つかった場合は、その値が返され、参照プロセスが終了します。
  • 一致するものが見つからない場合、ルックアップ プロセスはビジュアル ツリーを上方向に検索し、各親要素のリソース ディクショナリをチェックします。 要求されたキーが見つかった場合は、その値が返され、参照プロセスが終了します。 それ以外の場合、ルート要素に到達するまでプロセスは上向きに続行されます。
  • ルート要素で一致するものが見つからない場合は、アプリケーション レベルのリソース ディクショナリが調べられます。
  • 一致がまだ見つからない場合は、a XamlParseException がスローされます。

したがって、XAML パーサーが拡張またはDynamicResourceマークアップ拡張をStaticResource検出すると、見つかった最初の一致を使用して、ビジュアル ツリー内を移動して、一致するキーを検索します。 この検索がページで終了し、キーがまだ見つからない場合、XAML パーサーは、オブジェクトにアタッチされているキーをApp検索ResourceDictionaryします。 キーがまだ見つからない場合は、例外がスローされます。

リソースをオーバーライドする

リソースがキーを共有する場合、ビジュアル ツリーで下位に定義されたリソースが、上位に定義されているリソースよりも優先されます。 たとえば、アプリケーション レベルでリソースをAppBackgroundColorAliceBlue設定すると、ページ レベルAppBackgroundColorのリソースTealがオーバーライドされます。 同様に、ページ レベル AppBackgroundColor のリソースは、コントロール レベル AppBackgroundColor のリソースによってオーバーライドされます。

スタンドアロン リソース ディクショナリ

派生 ResourceDictionary クラスは、スタンドアロンの XAML ファイルに含めることもできます。 その後、XAML ファイルをアプリケーション間で共有できます。

このようなファイルを作成するには、新しい コンテンツ ビュー または コンテンツ ページ 項目をプロジェクトに追加します (ただし、C# ファイルのみの コンテンツ ビューコンテンツ ページ は追加しません)。 分離コード ファイルを削除し、XAML ファイルで基本クラス ContentViewContentPageResourceDictionaryの名前を変更します。 さらに、ファイルの x:Class ルート タグから属性を削除します。

次の XAML の例は、ResourceDictionaryMyResourceDictionary.xaml という名前を示しています。

<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>

この例では、型の ResourceDictionary オブジェクト DataTemplateである 1 つのリソースが含まれています。 MyResourceDictionary.xaml は、別のリソース ディクショナリにマージすることで使用できます。

既定では、リンカーの動作がすべてのアセンブリをリンクするように設定されている場合、リンカーはリリース ビルドからスタンドアロン XAML ファイルを削除します。 スタンドアロンの XAML ファイルがリリース ビルドに残っていることを確認するには、次の手順を実行します。

  1. スタンドアロン XAML ファイルを含むアセンブリにカスタム Preserve 属性を追加します。 詳細については、「 コードの保持」を参照してください。

  2. Preserveアセンブリ レベルで属性を設定します。

    [assembly:Preserve(AllMembers = true)]
    

リンクの詳細については、「 Xamarin.iOS アプリのリンクとAndroid でのリンク」を参照してください。

結合されたリソース ディクショナリ

マージされたリソース ディクショナリは、1 つまたは複数の ResourceDictionary オブジェクトを別 ResourceDictionaryのオブジェクトに結合します。

ローカル リソース ディクショナリのマージ

ローカル ResourceDictionary ファイルを別ResourceDictionaryのファイルにマージするには、リソースを含む XAML ファイルのファイル名にプロパティが設定されたオブジェクトSourceを作成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 ファイルのルート タグから削除できます。

重要

このプロパティは Source XAML からのみ設定できます。

他のアセンブリからリソース ディクショナリをマージする

A ResourceDictionary を別ResourceDictionaryのプロパティに追加MergedDictionariesResourceDictionaryしてマージすることもできます。 この手法を使用すると、リソース ディクショナリが存在するアセンブリに関係なく、リソース ディクショナリをマージできます。 外部アセンブリからリソース ディクショナリをマージするには、ビルド アクションを EmbeddedResource に設定し、分離コード ファイルを作成し、ファイルのルート タグに属性を定義x:Classする必要ResourceDictionaryがあります。

警告

ResourceDictionary クラスでは MergedWith プロパティも定義されます。 ただし、このプロパティは非推奨となり、使用されなくなりました。

次のコード例は、ページ レベルResourceDictionaryのコレクションにMergedDictionaries追加される 2 つのリソース ディクショナリを示しています。

<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>

この例では、同じアセンブリのリソース ディクショナリと外部アセンブリのリソース ディクショナリが、ページ レベルのリソース ディクショナリにマージされます。 さらに、プロパティ要素タグ内の他 ResourceDictionaryMergedDictionaries オブジェクトや、それらのタグの外部に他のリソースを追加することもできます。

重要

1 つのプロパティ要素タグResourceDictionaryは 1 つだけMergedDictionariesですが、必要な数ResourceDictionaryのオブジェクトをそこに配置できます。

マージされたリソースが ResourceDictionary 同じ x:Key 属性値を共有する場合は、 Xamarin.Forms 次のリソース優先順位を使用します。

  1. リソース ディクショナリにローカルなリソース。
  2. コレクションを介して MergedDictionaries マージされたリソース ディクショナリに含まれるリソースは、プロパティに一覧表示される逆の順序で MergedDictionaries 指定します。

注意

アプリケーションに複数の大規模なリソース ディクショナリが含まれている場合、リソース ディクショナリの検索は計算負荷の高いタスクになる可能性があります。 そのため、不要な検索を回避するには、アプリケーション内の各ページで、ページに適したリソース ディクショナリのみを使用するようにする必要があります。

他の Xamarin ビデオは、Channel 9 および YouTube でご覧いただけます。