リソース ディクショナリResource Dictionaries

サンプルのダウンロードサンプルをダウンロードします。Download Sample Download the sample

XAML リソースは、Xamarin. フォームアプリケーション全体で共有および再利用できるオブジェクトの定義です。これらのリソースオブジェクトは、リソースディクショナリに格納されます。XAML resources are definitions of objects that can be shared and re-used throughout a Xamarin.Forms application. These resource objects are stored in a resource dictionary.

A ResourceDictionary Xamarin.Forms アプリケーションで使用されるリソースのリポジトリです。A ResourceDictionary is a repository for resources that are used by a Xamarin.Forms application. 一般的なリソースが含まれている、ResourceDictionary含めるスタイルコントロール テンプレートデータ テンプレート色、およびコンバーター。Typical resources that are stored in a ResourceDictionary include styles, control templates, data templates, colors, and converters.

XAML に格納されているリソースで、ResourceDictionary取得して使用して要素に適用できるし、StaticResourceマークアップ拡張機能。In XAML, resources that are stored in a ResourceDictionary can then be retrieved and applied to elements by using the StaticResource markup extension. C# の場合は、リソース定義することもに、ResourceDictionaryを取得して、文字列ベースのインデクサーを使用して要素に適用します。In C#, resources can also be defined in a ResourceDictionary and then retrieved and applied to elements by using a string-based indexer. ただし、使用する利点のほとんどは、ResourceDictionaryで c# の場合は、共有オブジェクトは単にフィールドまたはプロパティとして格納されているし、しない直接アクセスに最初から取得ディクショナリ。However, there's little advantage to using a ResourceDictionary in C#, as shared objects can simply be stored as fields or properties, and accessed directly without having to first retrieve them from a dictionary.

ResourceDictionary の作成と使用Create and consume a ResourceDictionary

リソースが定義されている、 ResourceDictionary 、次のいずれかに設定されているResourcesプロパティ。Resources are defined in a ResourceDictionary that is then set to one of the following Resources properties:

Xamarin.Forms のプログラムにはから派生したクラス 1 つだけにはが含まれていますApplication多くの場合を使用して、多くのクラスから派生するが、 VisualElement(ページ、レイアウト、コントロールなど)。A Xamarin.Forms program contains only one class that derives from Application but often makes use of many classes that derive from VisualElement, including pages, layouts, and controls. これらのオブジェクトのいずれかがそのResourcesプロパティに設定、ResourceDictionaryします。Any of these objects can have its Resources property set to a ResourceDictionary. 特定の配置場所を選択するResourceDictionary影響は、リソースを使用できます。Choosing where to put a particular ResourceDictionary impacts where the resources can be used:

  • 内のリソースをResourceDictionaryなど、ビューに接続されるButtonまたはLabelのためこれは非常に便利なのみに、その特定のオブジェクトに適用できます。Resources in a ResourceDictionary that is attached to a view such as Button or Label can only be applied to that particular object, so this is not very useful.
  • 内のリソースをResourceDictionaryなどのレイアウトにアタッチされているStackLayoutまたはGridレイアウトとそのレイアウトのすべての子に適用できます。Resources in a ResourceDictionary attached to a layout such as StackLayout or Grid can be applied to the layout and all the children of that layout.
  • 内のリソースをResourceDictionary定義されているページとそのすべての子ページにレベルは適用できます。Resources in a ResourceDictionary defined at the page level can be applied to the page and to all its children.
  • 内のリソースをResourceDictionary定義されているアプリケーションで、アプリケーション全体でレベルを適用できます。Resources in a ResourceDictionary defined at the application level can be applied throughout the application.

次の XAML には、アプリケーション レベルで定義されているリソースが表示されます。ResourceDictionaryで、 App.xaml標準 Xamarin.Forms プログラムの一部として作成されたファイル。The following XAML shows resources defined in an application level ResourceDictionary in the App.xaml file created as part of the standard Xamarin.Forms program:

<Application ...>
    <Application.Resources>
        <ResourceDictionary>
            <Color x:Key="PageBackgroundColor">Yellow</Color>
            <Color x:Key="HeadingTextColor">Black</Color>
            <Color x:Key="NormalTextColor">Blue</Color>
            <Style x:Key="LabelPageHeadingStyle" TargetType="Label">
                <Setter Property="FontAttributes" Value="Bold" />
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="TextColor" Value="{StaticResource HeadingTextColor}" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

これは、ResourceDictionary定義 3 Color リソースと Style リソース。This ResourceDictionary defines three Color resources and a Style resource. 詳細については、Appクラスを参照してくださいApp クラスします。For more information about the App class, see App Class.

明示的な Xamarin.Forms 3.0 以降ではResourceDictionaryタグは必要ありません。Beginning in Xamarin.Forms 3.0, the explicit ResourceDictionary tags are not required. ResourceDictionaryオブジェクトが自動的に作成され、間で直接、リソースを挿入することができます、Resourcesプロパティ要素タグ。The ResourceDictionary object is created automatically, and you can insert the resources directly between the Resources property-element tags:

<Application ...>
    <Application.Resources>
        <Color x:Key="PageBackgroundColor">Yellow</Color>
        <Color x:Key="HeadingTextColor">Black</Color>
        <Color x:Key="NormalTextColor">Blue</Color>
        <Style x:Key="LabelPageHeadingStyle" TargetType="Label">
            <Setter Property="FontAttributes" Value="Bold" />
            <Setter Property="HorizontalOptions" Value="Center" />
            <Setter Property="TextColor" Value="{StaticResource HeadingTextColor}" />
        </Style>
    </Application.Resources>
</Application>

各リソースを使用して指定されているキーには、x:Key属性には、ディクショナリ キーになりますが、ResourceDictionaryします。Each resource has a key that is specified using the x:Key attribute, which becomes it dictionary key in the ResourceDictionary. リソースを取得するキーが使用される、ResourceDictionaryによって、 StaticResource マークアップ拡張機能、内で定義された追加のリソースを示す次の XAML コードの例のように、 StackLayout:The key is used to retrieve a resource from the ResourceDictionary by the StaticResource markup extension, as demonstrated in the following XAML code example that shows additional resources defined within the StackLayout:

<StackLayout Margin="0,20,0,0">
  <StackLayout.Resources>
    <ResourceDictionary>
      <Style x:Key="LabelNormalStyle" TargetType="Label">
        <Setter Property="TextColor" Value="{StaticResource NormalTextColor}" />
      </Style>
      <Style x:Key="MediumBoldText" TargetType="Button">
        <Setter Property="FontSize" Value="Medium" />
        <Setter Property="FontAttributes" Value="Bold" />
      </Style>
    </ResourceDictionary>
  </StackLayout.Resources>
  <Label Text="ResourceDictionary Demo" Style="{StaticResource LabelPageHeadingStyle}" />
    <Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries."
           Margin="10,20,10,0"
           Style="{StaticResource LabelNormalStyle}" />
    <Button Text="Navigate"
            Clicked="OnNavigateButtonClicked"
            TextColor="{StaticResource NormalTextColor}"
            Margin="0,20,0,0"
            HorizontalOptions="Center"
            Style="{StaticResource MediumBoldText}" />
</StackLayout>

最初の Label インスタンスを取得し、使用、LabelPageHeadingStyleアプリケーション レベルで定義されているリソースResourceDictionary、2 つ目Labelインスタンスの取得および使用、 LabelNormalStyle制御レベルで定義されているリソースResourceDictionaryします。The first Label instance retrieves and consumes the LabelPageHeadingStyle resource defined in the application level ResourceDictionary, with the second Label instance retrieving and consuming the LabelNormalStyle resource defined in the control level ResourceDictionary. 同様に、 Button インスタンスを取得し、使用、NormalTextColorアプリケーション レベルで定義されているリソースResourceDictionary、およびMediumBoldText制御レベルで定義されているリソースResourceDictionaryします。Similarly, the Button instance retrieves and consumes the NormalTextColor resource defined in the application level ResourceDictionary, and the MediumBoldText resource defined in the control level ResourceDictionary. 次のスクリーン ショットに示すように外観が発生します。This results in the appearance shown in the following screenshots:

ResourceDictionary リソースの消費Consuming ResourceDictionary Resources

注意

1 つのページに固有のリソースは、アプリケーション レベルのリソース ディクショナリをそのため、ページで必要なときに、リソースの代わりに、アプリケーションの起動時に解析されますに含めることはできません。Resources that are specific to a single page shouldn't be included in an application level resource dictionary, as such resources will then be parsed at application startup instead of when required by a page. 詳細については、次を参照してください。アプリケーション リソース ディクショナリのサイズを減らすします。For more information, see Reduce the Application Resource Dictionary Size.

リソースの上書きOverride resources

ときにResourceDictionaryのリソースを共有x:Key属性値は、ビューの階層内で下に定義されているリソースは優先を以上定義されています。When ResourceDictionary resources share x:Key attribute values, resources defined lower in the view hierarchy will take precedence over those defined higher up. たとえば、設定、PageBackgroundColorリソースをBlueアプリケーションでレベルがページ レベルで上書きされているPageBackgroundColorリソースに設定YellowFor example, setting the PageBackgroundColor resource to Blue at the application level will be overridden by a page level PageBackgroundColor resource set to Yellow. ページ レベルでは同様に、PageBackgroundColor制御レベルによってリソースが上書きされますPageBackgroundColorリソース。Similarly, a page level PageBackgroundColor resource will be overridden by a control level PageBackgroundColor resource. この優先順位は次の XAML コード例について説明します。This precedence is demonstrated by the following XAML code example:

<ContentPage ... BackgroundColor="{StaticResource PageBackgroundColor}">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Color x:Key="PageBackgroundColor">Blue</Color>
            <Color x:Key="NormalTextColor">Yellow</Color>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout Margin="0,20,0,0">
        ...
        <Label Text="ResourceDictionary Demo" Style="{StaticResource LabelPageHeadingStyle}" />
        <Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries."
               Margin="10,20,10,0"
               Style="{StaticResource LabelNormalStyle}" />
        <Button Text="Navigate"
                Clicked="OnNavigateButtonClicked"
                TextColor="{StaticResource NormalTextColor}"
                Margin="0,20,0,0"
                HorizontalOptions="Center"
                Style="{StaticResource MediumBoldText}" />
    </StackLayout>
</ContentPage>

元のPageBackgroundColorNormalTextColorによって、アプリケーション レベルで定義されている、インスタンスが上書きされます、PageBackgroundColorNormalTextColorページ レベルで定義されているインスタンス。The original PageBackgroundColor and NormalTextColor instances, defined at the application level, are overridden by the PageBackgroundColor and NormalTextColor instances defined at page level. したがって、ページの背景色が青と、次のスクリーン ショットに示すよう、ページ上のテキストが、黄色になります。Therefore, the page background color becomes blue, and the text on the page becomes yellow, as demonstrated in the following screenshots:

ResourceDictionary リソースの上書きOverriding ResourceDictionary Resources

ただし、注意のバック グラウンド バー、 NavigationPage 黄色のまま、ため、 BarBackgroundColor の値に設定されて、PageBackgroundColorアプリケーションで定義されているリソースレベルResourceDictionaryします。However, note that the background bar of the NavigationPage is still yellow, because the BarBackgroundColor property is set to the value of the PageBackgroundColor resource defined in the application level ResourceDictionary.

ResourceDictionary優先順位を考慮するもう1つの方法を次に示します。XAML パーサーは、をStaticResource検出すると、見つかった最初の一致を使用して、ビジュアルツリーの上に移動することで、一致するキーを検索します。Here's another way to think about ResourceDictionary precedence: When the XAML parser encounters a StaticResource, it searches for a matching key by traveling up through the visual tree, using the first match it finds. XAML パーサーが検索ページでこの検索を終了し、キーもまだ検出された場合、ResourceDictionaryにアタッチされている、Appオブジェクト。If this search ends at the page and the key still hasn't been found, the XAML parser searches the ResourceDictionary attached to the App object. でも、キーが存在しない場合は、例外が発生します。If the key is still not found, an exception is raised.

スタンドアロンリソースディクショナリStand-alone resource dictionaries

派生したクラスResourceDictionary別のスタンドアロン ファイルにもできます。A class derived from ResourceDictionary can also be in a separate stand-alone file. (から派生したクラスより正確にResourceDictionary通常必要がある、_ペア_ファイルの XAML ファイルの分離コード ファイル内のリソースが定義されているため、InitializeComponent呼び出しも必要です)。結果のファイルは、アプリケーション間で共有できます。(More precisely, a class derived from ResourceDictionary generally requires a pair of files because the resources are defined in a XAML file but a code-behind file with an InitializeComponent call is also necessary.) The resultant file can then be shared among applications.

このようなファイルを作成するには、追加、新しいコンテンツ ビューまたはコンテンツ ページ項目をプロジェクト (ではなく、コンテンツ ビューまたはコンテンツ ページでc# ファイルのみ)。To create such a file, add a new Content View or Content Page item to the project (but not a Content View or Content Page with only a C# file). XAML ファイルと c# ファイルの両方でから基底クラスの名前を変更ContentViewまたはContentPageResourceDictionaryします。In both the XAML file and C# file, change the name of the base class from ContentView or ContentPage to ResourceDictionary. XAML ファイルでは、基底クラスの名前は、最上位要素です。In the XAML file, the name of the base class is the top-level element.

次の XAML の例は、 ResourceDictionary というMyResourceDictionary:The following XAML example shows a ResourceDictionary named MyResourceDictionary:

<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
                    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                    x:Class="ResourceDictionaryDemo.MyResourceDictionary">
    <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型のオブジェクトは、1 つのリソースを含むDataTemplateします。This ResourceDictionary contains a single resource, which is an object of type DataTemplate.

インスタンスを作成できるMyResourceDictionaryのペアの間に配置してResourcesプロパティ要素タグをたとえばで、 ContentPage:You can instantiate MyResourceDictionary by putting it between a pair of Resources property-element tags, for example, in a ContentPage:

<ContentPage ...>
    <ContentPage.Resources>
        <local:MyResourceDictionary />
    </ContentPage.Resources>
    ...
</ContentPage>

インスタンスMyResourceDictionaryに設定されている、Resourcesのプロパティ、ContentPageオブジェクト。An instance of MyResourceDictionary is set to the Resources property of the ContentPage object.

ただし、この方法にはいくつかの制限があります。のプロパティはResources 、この1つResourceDictionaryだけを参照します。ContentPageHowever, this approach has some limitations: The Resources property of the ContentPage references only this one ResourceDictionary. などの他のオプションが必要なほとんどの場合、ResourceDictionaryインスタンスとおそらく他のリソースもします。In most cases, you want the option of including other ResourceDictionary instances and perhaps other resources as well.

このタスクでは、マージされたリソース ディクショナリが必要です。This task requires merged resource dictionaries.

マージされたリソースディクショナリMerged resource dictionaries

マージされたリソースディクショナリはResourceDictionary 、1つResourceDictionaryまたは複数のオブジェクトを別のオブジェクトに結合します。Merged resource dictionaries combine one or more ResourceDictionary objects into another ResourceDictionary.

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

ローカルResourceDictionaryを別ResourceDictionaryのにマージするには、 Sourceプロパティにリソースを含む XAML ファイルのファイル名を設定します。A local ResourceDictionary can be merged into another ResourceDictionary by setting the Source property to the filename of the XAML file with the resources:

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

この構文は、クラスをMyResourceDictionaryインスタンス化しません。This syntax does not instantiate the MyResourceDictionary class. 代わりに、XAML ファイルを参照します。Instead, it references the XAML file. そのため、 Sourceプロパティを設定するときに、分離コードファイル (MyResourceDictionary.xaml.cs) は必要なく、属性はx:Class myresourcedictionary .xamlファイルのルートタグから削除できます。For that reason, when setting the Source property, the code-behind file (MyResourceDictionary.xaml.cs) isn't required, and the x:Class attribute can be removed from the root tag of the MyResourceDictionary.xaml file. さらに、この方法を使用してリソースディクショナリをマージする場合、Xamarin にResourceDictionaryよってが自動的ResourceDictionaryにインスタンス化されるため、外側のタグは必要ありません。In addition, when merging resource dictionaries using this approach, Xamarin.Forms will automatically instantiate the ResourceDictionary, hence the outer ResourceDictionary tags are not required.

重要

プロパティSourceは、XAML からのみ設定できます。The Source property can only be set from XAML.

他のアセンブリからリソースディクショナリをマージするMerge resource dictionaries from other assemblies

は、 ResourceDictionary MergedDictionaries ResourceDictionary のプロパティに追加することResourceDictionaryで、別のにマージすることもできます。A ResourceDictionary can also be merged into another ResourceDictionary by adding it into the MergedDictionaries property of the ResourceDictionary. この手法では、リソースディクショナリが配置されているアセンブリに関係なく、リソースディクショナリをマージできます。This technique allows resource dictionaries to be merged, regardless of the assembly in which they reside.

重要

クラスResourceDictionaryは、 MergedWithプロパティも定義します。The ResourceDictionary class also defines a MergedWith property. ただし、このプロパティは非推奨とされているため、使用できなくなりました。However, this property has been deprecated and should no longer be used.

次のコード例はMyResourceDictionary 、ページレベルResourceDictionaryMergedDictionariesコレクションに追加されることを示しています。The following code example shows MyResourceDictionary being added to the MergedDictionaries collection of a page level ResourceDictionary:

<ContentPage ...
             xmlns:local="clr-namespace:ResourceDictionaryDemo">
    <ContentPage.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <local:MyResourceDictionary />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </ContentPage.Resources>
    ...
</ContentPage>

次の例は、同じMyResourceDictionaryアセンブリに存在するのインスタンスをResourceDictionaryに追加しています。This example shows an instance of MyResourceDictionary, which resides in the same assembly, being added to the ResourceDictionary. さらに、他のアセンブリ、 ResourceDictionary MergedDictionariesプロパティ要素タグ内の他のオブジェクト、その他のリソース (タグ以外) からリソースディクショナリを追加することもできます。In addition, you can also add resource dictionaries from other assemblies, other ResourceDictionary objects within the MergedDictionaries property-element tags, and other resources outside of those tags:

<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を1つだけ含めることができますが、そこにResourceDictionary必要な数のオブジェクトを含めることができます。 ResourceDictionaryThere can be only one MergedDictionaries property-element tag in a ResourceDictionary, but you can put as many ResourceDictionary objects in there as you want.

マージする際に ResourceDictionary リソースが同じ共有x:Key属性値は、Xamarin.Forms は、次のリソースの優先順位を使用します。When merged ResourceDictionary resources share identical x:Key attribute values, Xamarin.Forms uses the following resource precedence:

  1. リソース ディクショナリのローカル リソース。The resources local to the resource dictionary.
  2. 使用してマージされたリソース ディクショナリに含まれるリソース、MergedDictionariesに登録されている逆の順序で、コレクション、MergedDictionariesプロパティ。The resources contained in the resource dictionaries that were merged via the MergedDictionaries collection, in the reverse order they are listed in the MergedDictionaries property.

注意

アプリケーションが複数含まれている場合に、負荷の高いタスク リソース ディクショナリを検索することができますサイズの大きいリソース ディクショナリ。Searching resource dictionaries can be a computationally intensive task if an application contains multiple, large resource dictionaries. そのため、不要な検索を避けるため、アプリケーション内の各ページだけが、ページに適切なリソース ディクショナリを使用するを確認する必要があります。Therefore, to avoid unnecessary searching, you should ensure that each page in an application only uses resource dictionaries that are appropriate to the page.

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