web-dev-qa-db-ja.com

マージされた辞書を含むリソースディクショナリの参照に関する問題

いくつかのリソースディクショナリXAMLファイルを含むライブラリCommonLibraryWpfThemesがあります。私のThemes/Generic.xmlファイルには、他のすべてのファイルをマージするResourceDictionary.MergedDictionaries宣言が含まれています。

Generic.xaml

<ResourceDictionary
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml">
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/BrushDictionary.xaml" />
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/TextBlockDictionary.xaml" />
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/LabelDictionary.xaml" />
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/ButtonDictionary.xaml" />
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/WindowDictionary.xaml" />
    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

私のアプリケーションプロジェクトでは、CommonLibraryWpfThemesへの参照があり、App.xamlファイルでGeneric.xmlを明示的に参照しています。

App.xaml-失敗

<Application
    x:Class="MyApp.App"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary
            Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" />
    </Application.Resources>
</Application>

これは機能しません。アプリを実行すると、次のエラーが表示されます。

System.Windows.Markup.XamlParseException occurred
  Message="Cannot find resource named '{_fadedOrangeBrush}'. Resource names are case sensitive.  Error at object 'System.Windows.Setter' in markup file 'CommonLibraryWpfThemes;component/ResourceDictionaries/WindowDictionary.xaml' Line 18 Position 13."
  Source="PresentationFramework"
  LineNumber=18
  LinePosition=13

Generic.xamlの内容をApp.xamlに直接配置すると、すべてが正常に機能します。

App.xaml-SUCCEEDS

<Application
    x:Class="MyApp.App"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/BrushDictionary.xaml" />
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/TextBlockDictionary.xaml" />
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/LabelDictionary.xaml" />
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/ButtonDictionary.xaml" />
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/ResourceDictionaries/WindowDictionary.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

たぶん私はこれについて間違った方法で行っています。私の目標は、個々のファイルをすべてリストすることなく、複数のアプリケーションからすべてのテーマリソースを簡単に参照できるようにすることです。これを行うための推奨される方法はありますか? (注:複数のテーマを切り替えるつもりはありません。テーマは1つだけです。)

おまけとして、誰かがVisual Studioのデザイナーを壊さずに外部ライブラリのリソースを参照する方法を教えてくれたら嬉しいです。

ありがとう。

編集:

ResourceDictionary.MergedDictionary要素でResourceDictionaryをラップしようとしましたが、それも機能しませんでした(同じエラーが表示されます)。

<Application
    x:Class="MyApp.App"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary
                    Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>
44
devuxer

ここで以前の同様の質問に回答しました。 マージされた辞書をマージされた辞書に追加する 質問を参照してください。

これは最適化のバグです。 Microsoft Connect/DefaultStyleKeyスタイルが内部MergedDictionariesに見つかりません :を参照してください。

XAMLですべてのオブジェクトを作成するときに、デフォルトスタイル(つまり、Typeのキーを持つスタイル)が存在する場合、そのスタイルを適用する必要があります。ご想像のとおり、(暗黙の)ルックアップを可能な限り軽量にするために、いくつかのパフォーマンス最適化があります。それらの1つは、「デフォルトスタイルを含む」というフラグが立てられていない限り、リソースディクショナリの内部を調べないことです。バグがあります:すべてのデフォルトスタイルがマージされた辞書の3レベル(またはそれ以上)にネストされている場合、最上位の辞書にはフラグが付けられないため、検索はスキップされます。回避策は、デフォルトのスタイルをルートディクショナリの何かに配置することです。

そのため、ルートディクショナリにダミースタイルを追加すると、これが修正されます。例

<Application x:Class="MyApp.App"  
             xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"  
             xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml">  
    <Application.Resources> 
        <ResourceDictionary> 
            <ResourceDictionary.MergedDictionaries> 
                <ResourceDictionary 
                    Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" /> 
                </ResourceDictionary.MergedDictionaries> 
            <!-- Dummy Style, anything you won't use goes --> 
            <Style TargetType="{x:Type Rectangle}" /> 
        </ResourceDictionary> 
    </Application.Resources> 
</Application>   
67
Fredrik Hedblad

App.xaml.csのコンストラクタを確認して、InitializeComponent()を呼び出します。これがリソースディクショナリをマージします...

12
Chris

generic.xamlを参照する必要はまったくありません。組み込みのサポートがあります。ただし、これは、明示的に設定しないデフォルトのスタイル設定を提供することを意味します。明示的に設定されたスタイル/テンプレートは、明示的に参照されたres辞書から取得可能である必要があります。

(わかりやすくするために編集)

これの1つの例外はApp.xamlです。ここでは、特定のリソースディクショナリを参照する必要なく、定義されたリソースがアプリ全体からアクセス可能になります。リソース自体は、名前でアクセスできる必要があります。

これが失敗する理由

<Application.Resources>
    <ResourceDictionary
        Source="/CommonLibraryWpfThemes;component/Themes/Generic.xaml" />
</Application.Resources>

MergedDictionaryラッパーでラップしなかったため、マージした辞書に追加したためだと思います。リソースへの直接追加は、ローカルで宣言したリソースに対してのみ機能します。スタイルなど。

ただし、前に言ったように、generic.xamlをどこにでもマージする必要はありません。スタイル以外で使用されるブラシやその他のリソースをリファクタリングし、app.xamlのリソースのみをマージする必要があります。

また、スタイルが「デフォルトスタイル」の動作をするためにgeneric.xamlにある必要はないことに注意してください-要素のタイプに等しいキーを持つスタイルにアクセスできる場合(グローバルまたはローカルリソース内)、デフォルトのスタイルとしてのスタイル。 generic.xamlは便利です。

this answerを確認してください。

他のカスタムブラシなどについては、それらのリソースを明示的に参照する必要があります。

WindowDictionary.xamlの内容も確認する必要があります。このエラーには特定の匂いがあります。

4
Kenan E. K.

ユニットテストでこのエラーが発生していましたが、上記のChrisの答えから、必要な手がかりが得られました。基本的に、最初にテストした方法では、次のようにしました。

        MyApplication.App app = new MyApplication.App();
        app.InitializeComponent();

そして突然、私のページ用のテンプレートを見つけることができました。注:これは、App.csのユニットテストも行う場合、アプリのインスタンスが既に存在するかどうかを確認する必要があることを意味します。

0
ouflak