次の方法で共有


ResourceDictionary と XAML リソースの参照

XAML を使用して、アプリの UI またはリソースを定義できます。 リソースは、通常、複数回使用することが予想されるオブジェクトの定義です。 後で XAML リソースを参照するには、その名前のように機能するリソースのキーを指定します。 アプリ全体またはアプリ内の任意の XAML ページからリソースを参照できます。 リソースは、Windows ランタイム XAML の ResourceDictionary 要素を使用して定義できます。 その後、 StaticResource マークアップ拡張機能または ThemeResource マークアップ拡張機能 を使用して、リソース 参照できます。

XAML リソースとして最も頻繁に宣言する XAML 要素には、 StyleControlTemplate、アニメーション コンポーネント、 Brush サブクラスなどがあります。 ここでは、 ResourceDictionary リソースとキー付きリソースを定義する方法と、XAML リソースをアプリまたはアプリ パッケージの一部として定義する他のリソースとどのように関連するかを説明します。 また、 MergedDictionaries や ThemeDictionaries などのリソース ディクショナリの高度な機能についても説明 します

[前提条件]

XAML マークアップをしっかりと理解している。 XAML の概要を読むことをお勧めします。

XAML リソースを定義して使用する

XAML リソースは、マークアップから複数回参照されるオブジェクトです。 リソースは ResourceDictionary で定義されます。通常は、別のファイルまたはマークアップ ページの上部に定義されます。次のようになります。

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Page.Resources>
        <x:String x:Key="greeting">Hello world</x:String>
        <x:String x:Key="goodbye">Goodbye world</x:String>
    </Page.Resources>

    <TextBlock Text="{StaticResource greeting}" Foreground="Gray" VerticalAlignment="Center"/>
</Page>

この例では:

  • <Page.Resources>…</Page.Resources> - リソース ディクショナリを定義します。
  • <x:String> - キー "greeting" を使用してリソースを定義します。
  • {StaticResource greeting}- TextBlockText プロパティに割り当てられているキー "greeting" を使用してリソースを検索します。

手記ResourceDictionary に関連する概念を、アプリ パッケージを生成するコード プロジェクトの構成のコンテキストで説明されているリソース ビルド アクション、リソース (.resw) ファイル、またはその他の "リソース" と混同しないでください。

リソースは文字列である必要はありません。スタイル、テンプレート、ブラシ、色など、任意の共有可能なオブジェクトを指定できます。 ただし、コントロール、図形、およびその他 の FrameworkElementは共有できないため、再利用可能なリソースとして宣言することはできません。 共有の詳細については、このトピックで後述する 「XAML リソースを共有可能にする必要がある 」セクションを参照してください。

ここでは、ブラシと文字列の両方がリソースとして宣言され、ページ内のコントロールによって使用されます。

<Page
    x:Class="SpiderMSDN.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Page.Resources>
        <SolidColorBrush x:Key="myFavoriteColor" Color="green"/>
        <x:String x:Key="greeting">Hello world</x:String>
    </Page.Resources>

    <TextBlock Foreground="{StaticResource myFavoriteColor}" Text="{StaticResource greeting}" VerticalAlignment="Top"/>
    <Button Foreground="{StaticResource myFavoriteColor}" Content="{StaticResource greeting}" VerticalAlignment="Center"/>
</Page>

すべてのリソースにキーが必要です。 通常、そのキーは x:Key="myString"で定義された文字列です。 ただし、キーを指定する方法はいくつかあります。

  • StyleControlTemplate には TargetType が必要であり、x:Key が指定されていない場合は TargetType をキーとして使用します。 この場合、キーは実際の Type オブジェクトであり、文字列ではありません。 (以下の例を参照)
  • TargetType を持つ DataTemplate リソースでは、x:Key が指定されていない場合、TargetType がキーとして使用されます。 この場合、キーは実際の Type オブジェクトであり、文字列ではありません。
  • x:Key の代わりに x:Name を使用できます。 ただし、x:Name はリソースのコード ビハインド フィールドも生成します。 その結果、ページが読み込まれるときにフィールドを初期化する必要があるため、x:Name は x:Key よりも効率が低くなります。

StaticResource マークアップ拡張機能は、文字列名 (x:Key または x:Name) のみを使用してリソースを取得できます。 ただし、XAML フレームワークは、Style プロパティと ContentTemplate プロパティまたは ItemTemplate プロパティを設定していないコントロールに使用するスタイルとテンプレートを決定するときに、暗黙的なスタイル リソース (x:Key または x:Name ではなく TargetType を使用するリソース) も検索します。

ここでは、 Style には typeof(Button) の暗黙的なキーがあり、ページの下部にある Button では Style プロパティが指定されていないため、 typeof(Button)のキーを持つスタイルが検索されます。

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Page.Resources>
        <Style TargetType="Button">
            <Setter Property="Background" Value="Red"/>
        </Style>
    </Page.Resources>
    <Grid>
       <!-- This button will have a red background. -->
       <Button Content="Button" Height="100" VerticalAlignment="Center" Width="100"/>
    </Grid>
</Page>

暗黙的なスタイルとその動作の詳細については、スタイル設定コントロール および コントロールテンプレートを参照してください。

コードでリソースを検索する

他のディクショナリと同様に、リソース ディクショナリのメンバーにアクセスします。

Warnung

コードでリソース検索を実行すると、 Page.Resources ディクショナリ内のリソースのみが確認されます。 StaticResource マークアップ拡張機能とは異なり、リソースが最初のディクショナリに見つからない場合、コードは Application.Resources ディクショナリにフォールバックしません。

 

この例では、ページのリソース ディクショナリから redButtonStyle リソースを取得する方法を示します。

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Page.Resources>
        <Style TargetType="Button" x:Key="redButtonStyle">
            <Setter Property="Background" Value="red"/>
        </Style>
    </Page.Resources>
</Page>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            Style redButtonStyle = (Style)this.Resources["redButtonStyle"];
        }
    }
    MainPage::MainPage()
    {
        InitializeComponent();
        Windows::UI::Xaml::Style style = Resources().TryLookup(winrt::box_value(L"redButtonStyle")).as<Windows::UI::Xaml::Style>();
    }

コードからアプリ全体のリソースを検索するには、次に示すように 、Application.Current.Resources を使用してアプリのリソース ディクショナリを取得します。

<Application
    x:Class="MSDNSample.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SpiderMSDN">
    <Application.Resources>
        <Style TargetType="Button" x:Key="appButtonStyle">
            <Setter Property="Background" Value="red"/>
        </Style>
    </Application.Resources>

</Application>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            Style appButtonStyle = (Style)Application.Current.Resources["appButtonStyle"];
        }
    }
    MainPage::MainPage()
    {
        InitializeComponent();
        Windows::UI::Xaml::Style style = Application::Current().Resources()
                                                               .TryLookup(winrt::box_value(L"appButtonStyle"))
                                                               .as<Windows::UI::Xaml::Style>();
    }

コードでアプリケーション リソースを追加することもできます。

これを行うときは、2 つの点に留意する必要があります。

  • まず、ページでリソースの使用を試みる前に、リソースを追加する必要があります。
  • 次に、アプリのコンストラクターにリソースを追加することはできません。

次のように Application.OnLaunched メソッドにリソースを追加すると、両方の問題を回避できます。

// App.xaml.cs
    
sealed partial class App : Application
{
    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        Frame rootFrame = Window.Current.Content as Frame;
        if (rootFrame == null)
        {
            SolidColorBrush brush = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 0, 255, 0)); // green
            this.Resources["brush"] = brush;
            // … Other code that VS generates for you …
        }
    }
}
// App.cpp

void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
    Frame rootFrame{ nullptr };
    auto content = Window::Current().Content();
    if (content)
    {
        rootFrame = content.try_as<Frame>();
    }

    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == nullptr)
    {
        Windows::UI::Xaml::Media::SolidColorBrush brush{ Windows::UI::ColorHelper::FromArgb(255, 0, 255, 0) };
        Resources().Insert(winrt::box_value(L"brush"), winrt::box_value(brush));
        // … Other code that VS generates for you …

すべての FrameworkElement は ResourceDictionary を持つことができます

FrameworkElement は、コントロールが継承する基本クラスであり、 Resources プロパティを持っています。 そのため、任意の FrameworkElement にローカル リソース ディクショナリを追加できます。

ここでは、 PageBorder の両方にリソース ディクショナリがあり、どちらも "greeting" というリソースを持っています。 " textBlock2 " という名前の TextBlock は Border 内にあります。そのため、リソース参照は最初に Border のリソース、次に ページのリソース、次に アプリケーション リソースを検索します。 TextBlock は "Hola mundo" と読み取ります。

コードからその要素のリソースにアクセスするには、その要素の Resources プロパティを使用します。 XAML ではなくコード内で FrameworkElement のリソースにアクセスすると、親要素のディクショナリではなく、そのディクショナリ内でのみ検索されます。

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <x:String x:Key="greeting">Hello world</x:String>
    </Page.Resources>
    
    <StackPanel>
        <!-- Displays "Hello world" -->
        <TextBlock x:Name="textBlock1" Text="{StaticResource greeting}"/>

        <Border x:Name="border">
            <Border.Resources>
                <x:String x:Key="greeting">Hola mundo</x:String>
            </Border.Resources>
            <!-- Displays "Hola mundo" -->
            <TextBlock x:Name="textBlock2" Text="{StaticResource greeting}"/>
        </Border>

        <!-- Displays "Hola mundo", set in code. -->
        <TextBlock x:Name="textBlock3"/>
    </StackPanel>
</Page>

    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            textBlock3.Text = (string)border.Resources["greeting"];
        }
    }
    MainPage::MainPage()
    {
        InitializeComponent();
        textBlock3().Text(unbox_value<hstring>(border().Resources().TryLookup(winrt::box_value(L"greeting"))));
    }

マージされたリソース辞書

マージされたリソース ディクショナリは、1 つのリソース ディクショナリを別のリソース ディクショナリ (通常は別のファイル) に結合します。

ヒント Microsoft Visual Studio でリソース ディクショナリ ファイルを作成するには、[プロジェクト] メニューの [リソース ディクショナリの ] オプション を使用します。

ここでは、Dictionary1.xaml という別の XAML ファイルでリソース ディクショナリを定義します。

<!-- Dictionary1.xaml -->
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MSDNSample">

    <SolidColorBrush x:Key="brush" Color="Red"/>

</ResourceDictionary>

その辞書を使用するには、それをページの辞書とマージします。

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml"/>
            </ResourceDictionary.MergedDictionaries>

            <x:String x:Key="greeting">Hello world</x:String>

        </ResourceDictionary>
    </Page.Resources>

    <TextBlock Foreground="{StaticResource brush}" Text="{StaticResource greeting}" VerticalAlignment="Center"/>
</Page>

この例では、次の処理が行われます。 <Page.Resources>では、<ResourceDictionary>を宣言します。 XAML フレームワークは、リソースを <Page.Resources>に追加するときにリソース ディクショナリを暗黙的に作成します。ただし、この場合は、結合されたディクショナリを含むリソース ディクショナリだけを必要としません。

そのために、<ResourceDictionary>を宣言し、その後で、その <ResourceDictionary.MergedDictionaries> コレクションに項目を追加します。 これらの各エントリは、<ResourceDictionary Source="Dictionary1.xaml"/>の形式をとります。 複数のディクショナリを追加するには、最初のエントリの後に <ResourceDictionary Source="Dictionary2.xaml"/> エントリを追加するだけです。

<ResourceDictionary.MergedDictionaries>…</ResourceDictionary.MergedDictionaries>後、必要に応じて、メイン ディクショナリに追加のリソースを配置できます。 マージされた辞書のリソースは、通常の辞書と同様に使用できます。 上の例では、 {StaticResource brush} は子/マージされたディクショナリ (Dictionary1.xaml) でリソースを検索し、 {StaticResource greeting} はメイン ページ ディクショナリでそのリソースを検索します。

リソース参照シーケンスでは、 MergedDictionaries ディクショナリは、その ResourceDictionary の他のすべてのキー付きリソースをチェックした後にのみチェックされます。 そのレベルを検索すると、参照はマージされたディクショナリに到達し、 MergedDictionaries の各項目がチェックされます。 複数のマージされたディクショナリが存在する場合、これらのディクショナリは、 MergedDictionaries プロパティで宣言されている順序の逆でチェックされます。 次の例では、Dictionary2.xaml と Dictionary1.xaml の両方で同じキーが宣言されている場合、最初に Dictionary2.xaml のキーが使用されます。これは MergedDictionaries セットの最後であるためです。

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml"/>
                <ResourceDictionary Source="Dictionary2.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Page.Resources>

    <TextBlock Foreground="{StaticResource brush}" Text="greetings!" VerticalAlignment="Center"/>
</Page>

任意の ResourceDictionaryの範囲内で、辞書がキーの一意性をチェックされます。 ただし、そのスコープは、 異なる MergedDictionaries ファイル内の異なる項目にまたがって拡張されることはありません。

参照シーケンスの組み合わせと、マージされたディクショナリ スコープ間での一意のキーの強制の欠如を使用して、ResourceDictionary リソースのフォールバック値シーケンス 作成できます。 たとえば、アプリの状態とユーザー設定データに同期するリソース ディクショナリを使用して、シーケンス内の最後にマージされたリソース ディクショナリに特定のブラシの色のユーザー設定を格納できます。 ただし、ユーザー設定がまだ存在しない場合は、最初の MergedDictionaries ファイル内の ResourceDictionary リソースに同じキー文字列を定義し、フォールバック値として使用できます。 プライマリ リソース ディクショナリで指定した値は、マージされたディクショナリがチェックされる前に常にチェックされるので、フォールバック手法を使用する場合は、プライマリ リソース ディクショナリでそのリソースを定義しないでください。

テーマ リソースとテーマ ディクショナリ

ThemeResourceStaticResource に似ていますが、テーマが変更されるとリソース参照が再評価されます。

この例では、 TextBlock の前景を現在のテーマの値に設定します。

<TextBlock Text="hello world" Foreground="{ThemeResource FocusVisualWhiteStrokeThemeBrush}" VerticalAlignment="Center"/>

テーマ ディクショナリは、ユーザーが現在自分のデバイスで使用しているテーマによって異なるリソースを保持する、特殊な種類のマージされたディクショナリです。 たとえば、"明るい" テーマでは白のカラー ブラシを使用し、"濃色" テーマでは濃色ブラシを使用する場合があります。 ブラシは解決先のリソースを変更しますが、それ以外の場合は、ブラシをリソースとして使用するコントロールの構成が同じになる可能性があります。 メイン ディクショナリに項目をマージするプロパティとして MergedDictionaries を使用する代わりに、独自のテンプレートとスタイルでテーマ切り替え動作を再現するには、 ThemeDictionaries プロパティを使用します。

ThemeDictionaries 内の各 ResourceDictionary 要素には、x:Key 値が必要です。 この値は、関連するテーマ ("Default"、"Dark"、"Light"、"HighContrast" など) に名前を付けた文字列です。 通常、 Dictionary1Dictionary2 は、同じ名前で値が異なるリソースを定義します。

ここでは、明るいテーマには赤いテキストを、濃色テーマには青いテキストを使用します。

<!-- Dictionary1.xaml -->
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MSDNSample">

    <SolidColorBrush x:Key="brush" Color="Red"/>

</ResourceDictionary>

<!-- Dictionary2.xaml -->
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MSDNSample">

    <SolidColorBrush x:Key="brush" Color="blue"/>

</ResourceDictionary>

この例では、 TextBlock の前景を現在のテーマの値に設定します。

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.ThemeDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml" x:Key="Light"/>
                <ResourceDictionary Source="Dictionary2.xaml" x:Key="Dark"/>
            </ResourceDictionary.ThemeDictionaries>
        </ResourceDictionary>
    </Page.Resources>
    <TextBlock Foreground="{StaticResource brush}" Text="hello world" VerticalAlignment="Center"/>
</Page>

テーマ ディクショナリの場合、リソース参照に使用されるアクティブなディクショナリは、 ThemeResource マークアップ拡張機能 を使用して参照を行い、システムがテーマの変更を検出するたびに、動的に変更されます。 システムによって実行される参照動作は、アクティブなテーマを特定のテーマ ディクショナリの x:Key にマッピングすることによって行われます。

既定の XAML デザイン リソースでテーマ ディクショナリが構造化されている方法を調べると便利です。このリソースは、Windows ランタイムが既定でコントロールに使用するテンプレートと並行しています。 テキスト エディターまたは IDE を使用して、\(Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\<SDK バージョン>\Generic で XAML ファイルを開きます。 最初に generic.xaml でテーマ ディクショナリを定義する方法と、各テーマ ディクショナリで同じキーを定義する方法に注意してください。 その後、このような各キーは、テーマ ディクショナリの外部にあり、XAML で後で定義されるさまざまなキー要素のコンポジションの要素によって参照されます。 既定のコントロール テンプレートではなく、テーマ リソースと追加のテンプレートのみを含むデザイン用の個別の themeresources.xaml ファイルもあります。 テーマ領域は、generic.xaml に表示される内容の複製です。

XAML デザイン ツールを使用してスタイルとテンプレートのコピーを編集する場合、デザイン ツールは XAML デザイン リソース ディクショナリからセクションを抽出し、アプリとプロジェクトの一部である XAML ディクショナリ要素のローカル コピーとして配置します。

詳しくは、アプリで使用できるテーマ固有のリソースとシステム リソースの一覧については、 XAML テーマ リソースに関するページをご覧ください。

XAML リソース参照の検索動作

検索動作 は、XAML リソース システムが XAML リソースを検索する方法を説明する用語です。 検索は、キーがアプリの XAML 内のどこかから XAML リソース参照として参照されるときに発生します。 まず、リソース システムは、スコープに基づいてリソースの存在を確認する場所に対して予測可能な動作を持ちます。 リソースが初期スコープに見つからない場合、スコープは拡張されます。 検索動作は、XAML リソースがアプリまたはシステムによって定義される可能性がある場所とスコープ全体で継続されます。 可能なすべてのリソース参照の試行が失敗すると、多くの場合、エラーが発生します。 通常、開発プロセス中にこれらのエラーをなくす可能性があります。

XAML リソース参照の参照動作は、実際の使用状況が適用されるオブジェクトと、独自の Resources プロパティから始まります。 ResourceDictionary が存在する場合、その ResourceDictionary で、要求されたキーを持つ項目がチェックされます。 この第 1 レベルの参照は、通常は同じオブジェクト上のリソースを定義して参照しないため、ほとんど関係ありません。 実際、 Resources プロパティは、多くの場合、ここには存在しません。 XAML リソース参照は、XAML のほぼすべての場所から行うことができます。 FrameworkElement サブクラスのプロパティに限定されるわけではありません。

その後、検索シーケンスは、アプリのランタイム オブジェクト ツリー内の次の親オブジェクトをチェックします。 FrameworkElement.Resources が存在し、ResourceDictionary を保持している場合は、指定されたキー文字列を持つディクショナリ項目が要求されます。 リソースが見つかった場合、参照シーケンスが停止し、参照が行われた場所にオブジェクトが提供されます。 それ以外の場合、参照動作はオブジェクト ツリー ルートに向かって次の親レベルに進みます。 検索は、XAML のルート要素に到達するまで再帰的に上向きに続き、可能なすべての即時リソースの場所の検索を使い果たします。

このリソース参照動作を利用し、XAML マークアップ スタイルの規則として、ページのルート レベルですべての即時リソースを定義するのが一般的な方法です。

要求されたリソースが即時リソースで見つからない場合、次の参照手順は Application.Resources プロパティを確認することです。 Application.Resources は、複数のページによって参照されるアプリ固有のリソースをアプリのナビゲーション構造に配置するのに最適な場所です。

Von Bedeutung

ResourceDictionary に追加されるリソースの順序は、リソースが適用される順序に影響します。 XamlControlsResources ディクショナリは、多くの既定のリソース キーをオーバーライドするため、最初にApplication.Resourcesに追加して、アプリ内の他のカスタム スタイルやリソースをオーバーライドしないようにする必要があります。

コントロール テンプレートは参照検索の別の場所としてテーマ辞書に含まれています。 テーマ ディクショナリは、 ルートとして ResourceDictionary 要素を持つ 1 つの XAML ファイルです。 テーマディクショナリは、Application.Resourcesからマージされたディクショナリである可能性があります。 テーマ ディクショナリは、テンプレート化されたカスタム コントロールのコントロール固有のテーマ ディクショナリである場合もあります。

最後に、プラットフォーム リソースに対するリソース参照があります。 プラットフォーム リソースには、システム UI テーマごとに定義され、Windows ランタイム アプリの UI に使用するすべてのコントロールの既定の外観を定義するコントロール テンプレートが含まれます。 プラットフォーム リソースには、システム全体の外観とテーマに関連する一連の名前付きリソースも含まれます。 これらのリソースは技術的には MergedDictionaries 項目であるため、アプリの読み込み後に XAML またはコードから検索できます。 たとえば、システム テーマ リソースには、"SystemColorWindowTextColor" という名前のリソースが含まれます。 このリソースは 、アプリのテキストの色と、オペレーティング システムとユーザー設定に由来するシステム ウィンドウのテキストの色に一致する色定義を提供します。 アプリの他の XAML スタイルでこのスタイルを参照することも、コードでリソース参照値を取得することもできます (この例では Color にキャストします)。

詳しくは、XAML を使用する Windows アプリで使用できるテーマ固有のリソースとシステム リソースの一覧については、 XAML テーマ リソースに関するページを参照してください。

要求されたキーがこれらの場所でまだ見つからない場合は、XAML 解析エラー/例外が発生します。 特定の状況では、XAML 解析例外は、XAML マークアップ コンパイル アクションまたは XAML デザイン環境によって検出されない実行時例外である可能性があります。

リソース ディクショナリの階層化された参照動作のため、各リソースが異なるレベルで定義されている限り、キーと同じ文字列値を持つ複数のリソース項目を意図的に定義できます。 言い換えると、キーは特定の ResourceDictionary 内で一意である必要がありますが、一意性の要件はルックアップ動作シーケンス全体に拡張されません。 検索中に、正常に取得された最初のオブジェクトのみが XAML リソース参照に使用され、検索が停止します。 この動作を使用すると、アプリの XAML 内のさまざまな位置でキーによって同じ XAML リソースを要求できますが、XAML リソース参照の作成元のスコープとその特定の参照の動作に応じて、異なるリソースが返されます。

ResourceDictionary 内の参照を転送する

特定のリソース ディクショナリ内の XAML リソース参照は、キーで既に定義されているリソースを参照する必要があり、そのリソースはリソース参照の前に構文的に表示される必要があります。 前方参照は、XAML リソース参照では解決できません。 このため、別のリソース内から XAML リソース参照を使用する場合は、他のリソースによって使用されるリソースがリソース ディクショナリで最初に定義されるように、リソース ディクショナリ構造を設計する必要があります。

アプリ レベルで定義されたリソースは、即時リソースへの参照を作成できません。 これは、アプリ リソースが最初に (アプリが最初に開始されたとき、ナビゲーション ページコンテンツが読み込まれる前に) 処理されるため、前方参照を試みるのと同じです。 ただし、即時リソースはアプリ リソースへの参照を行うことができます。これは、前方参照の状況を回避するための便利な手法です。

XAML リソースは共有可能である必要があります

ResourceDictionaryにオブジェクトを存在させるには、そのオブジェクトは共有可能 である必要があります。

アプリのオブジェクト ツリーが構築され、実行時に使用される場合、オブジェクトはツリー内の複数の場所に存在できないため、共有可能であることが必要です。 内部的には、リソース システムは、各 XAML リソースが要求されたときにアプリのオブジェクト グラフで使用するリソース値のコピーを作成します。

一般に 、ResourceDictionary および Windows ランタイム XAML では、共有可能な使用のために次のオブジェクトがサポートされています。

必要な実装パターンに従う場合は、カスタム型を共有可能なリソースとして使用することもできます。 このようなクラスは、バッキング コード (または含めるランタイム コンポーネント) で定義し、XAML でリソースとしてインスタンス化します。 たとえば、オブジェクト データ ソースやデータ バインディング用の IValueConverter 実装 の例があります。

カスタム型には既定のコンストラクターが必要です。これは、XAML パーサーがクラスをインスタンス化するために使用するためです。 リソースとして使用されるカスタム型は、 UIElement を共有できないため、継承に UIElement クラスを含めることはできません (ランタイム アプリのオブジェクト グラフ内の 1 つの位置に存在する 1 つの UI 要素を常に表すことを意図しています)。

UserControl の使用スコープ

UserControl 要素には、定義スコープと使用スコープの固有の概念があるため、リソース参照の動作に特別な状況があります。 定義スコープから XAML リソース参照を作成する UserControl は、独自の定義スコープ参照シーケンス内でそのリソースの参照をサポートできる必要があります。つまり、アプリ リソースにアクセスすることはできません。 UserControl の使用スコープから、リソース参照は、(読み込まれたオブジェクト ツリー内のオブジェクトから作成された他のリソース参照と同様に) その使用状況ページ ルートに対する参照シーケンス内にあるものとして扱われ、アプリ リソースにアクセスできます。

ResourceDictionary と XamlReader.Load

ResourceDictionary は、XamlReader.Load メソッドのルートまたは XAML 入力の一部として使用できます。 このような参照がすべて読み込みのために送信された XAML に完全に自己完結している場合は、その XAML に XAML リソース参照を含めることもできます。 XamlReader.Load は、Application.Resourcesでなくても、他の ResourceDictionary オブジェクトを認識していないコンテキストで XAML を解析します。 また、{ThemeResource} に送信された XAML 内からを使用しないでください。

コードからの ResourceDictionary の使用

ResourceDictionary のシナリオのほとんどは、XAML でのみ処理されます。 ResourceDictionary コンテナーと、その中のリソースは、UI 定義ファイル内の XAML ファイルまたは XAML ノードのセットとして宣言します。 次に、XAML リソース参照を使用して、XAML の他の部分からそれらのリソースを要求します。 それでも、アプリの実行中に実行されるコードを使用して ResourceDictionary の内容を調整したり、少なくとも ResourceDictionary のコンテンツにクエリを実行してリソースが既に定義されているかどうかを確認したりするシナリオもあります。 これらのコード呼び出しは、ResourceDictionary インスタンスで行われるので、まず、オブジェクトツリー内のどこかにあるFrameworkElement.Resourcesを取得して、即座に使用できる ResourceDictionary を取り出すか、または別の方法で Application.Current.Resourcesを取得する必要があります…。

C# または Microsoft Visual Basic コードでは、インデクサー (Item) を使用して、特定の ResourceDictionary 内のリソースを参照できます。 ResourceDictionary は文字列キー付きディクショナリであるため、インデクサーは整数インデックスではなく文字列キーを使用します。 Visual C++ コンポーネント拡張機能 (C++/CX) コードでは、 Lookup を使用します

コードを使用して ResourceDictionary を調べたり変更したりする場合、 LookupItem などの API の動作は、即時リソースからアプリ リソースに走査されません。これは、XAML ページが読み込まれるときにのみ発生する XAML パーサーの動作です。 実行時に、キーのスコープは、その時点で使用している ResourceDictionary インスタンスに対して自己完結型になります。 ただし、そのスコープは MergedDictionaries に拡張されます。

また、 ResourceDictionary に存在しないキーを要求した場合は、エラーが発生しない可能性があります。戻り値は 単に null として指定できます。 ただし、返された null を値として使用しようとすると、エラーが発生する可能性があります。 このエラーは、 ResourceDictionary 呼び出しではなく、プロパティのセッターから発生します。 エラーを回避する唯一の方法は、プロパティが有効な値として null を 受け入れた場合です。 この動作と XAML 解析時の XAML 参照動作の違いに注意してください。解析時に XAML から指定されたキーを解決できないと、プロパティが null を受け入れた可能性がある場合でも、XAML 解析エラーが発生します。

マージされたリソース ディクショナリは、実行時にマージされたディクショナリを参照するプライマリ リソース ディクショナリのインデックス スコープに含まれます。 つまり、プライマリ ディクショナリの Item または Lookup を使用して、マージされたディクショナリで実際に定義されたオブジェクトを検索できます。 この場合、検索動作は解析時の XAML 参照動作に似ています。マージされたディクショナリに、それぞれが同じキーを持つ複数のオブジェクトがある場合、最後に追加されたディクショナリのオブジェクトが返されます。

Add (C# または Visual Basic) または Insert (C++/CX) を呼び出すことによって、既存の ResourceDictionary に項目を追加できます。 項目は、即時リソースまたはアプリ リソースに追加できます。 これらのいずれかの API 呼び出しにはキーが必要です。これは、 ResourceDictionary 内の各項目にキーが必要であるという要件を満たします。 ただし、実行時に ResourceDictionary に追加する項目は、XAML リソース参照には関係ありません。 XAML リソース参照に必要な検索は、アプリの読み込み時に XAML が最初に解析されたとき (またはテーマの変更が検出された場合) に発生します。 実行時にコレクションに追加されたリソースは使用できませんでした。 ResourceDictionary を変更しても、そのリソースの値を変更しても、既に取得されたリソースは無効になりません。

実行時に ResourceDictionary から項目を削除したり、一部またはすべての項目のコピーを作成したり、その他の操作を行うこともできます。 ResourceDictionary のメンバー リストは、使用可能な API を示します。 ResourceDictionary には基になるコレクション インターフェイスをサポートする投影 API があるため、API オプションは、C# と Visual Basic のどちらを使用しているか、C++/CX を使用しているかによって異なることに注意してください。

ResourceDictionary とローカリゼーション

XAML ResourceDictionary には、最初はローカライズされる文字列が含まれている場合があります。 その場合は、 ResourceDictionary ではなくプロジェクト リソースとしてこれらの文字列を格納します。 XAML から文字列を取り出し、代わりに所有する要素に x:Uid ディレクティブ 値を指定します。 次に、リソース ファイルでリソースを定義します。 XUIDValue .PropertyName の形式でリソース名を指定し、ローカライズが必要な文字列をリソース値として提供します。

カスタム リソース参照

高度なシナリオでは、このトピックで説明する XAML リソース参照参照動作とは異なる動作を持つクラスを実装できます。 これを行うには、CustomXamlResourceLoaderクラスを実装し、StaticResource または ThemeResourceを使用するのではなく、リソース参照用の CustomResource マークアップ拡張 使用して、その動作 アクセスできます。 ほとんどのアプリには、これを必要とするシナリオはありません。 詳細については、「 CustomXamlResourceLoader」を参照してください。