44

いくつかのリソースディクショナリXAMLファイルを含むライブラリCommonLibraryWpfThemesがあります。My 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-成功

<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をResourceDictionary.MergedDictionary要素でラップしようとしましたが、それも機能しませんでした(同じエラーが発生します)。

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

5 に答える 5

68

以前にここで同様の質問に回答しました。マージされたディクショナリをマージされたディクショナリに追加する質問を参照してください。

これは最適化のバグです。Microsoft Connect / DefaultStyleKey style not found in inner 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>   
于 2010-11-12T15:46:46.457 に答える
13

App.xaml.cs 呼び出しのコンストラクターを確認してください InitializeComponent() - これは、リソース ディクショナリをマージするものです...

于 2010-01-19T11:20:20.703 に答える
4

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

(明確にするために編集)

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

これが失敗する理由

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

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

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

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

この回答を確認してください。

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

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

于 2009-08-04T19:32:53.617 に答える
0

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

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

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

于 2012-11-20T08:31:27.877 に答える
-1

私の解決策はこちらです。回避策をクリックしてください。

于 2010-10-15T11:13:46.147 に答える