23

リソース ディクショナリのマージに問題がある WPF .net 4.5 アプリケーションがあります。

This SO questionおよびThis Questionとまったく同じ問題がありますが、受け入れられた解決策はうまくいきません。

次のように app.xaml で宣言されたリソース ディクショナリがあります (わかりやすくするために簡略化しています)。

<Application.Resources>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Skin/ResourceLibrary.xaml" />              
            <ResourceDictionary Source="Skin/Brushes/ColorStyles.xaml" />               
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>               
</Application.Resources>

問題: app.xaml にリストされている場合、アプリは ColorStyles ディクショナリを「表示」できますが、ResourceLibrary.xaml 内に移動またはネストすると、ColorStyles.xaml はアプリによって「表示」されず、静的リソースの欠落に関するエラーが発生します。現れる。

ResourceLibrary.xaml ディクショナリを作成する方法は次のとおりです (簡略化)。

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ResourceDictionary.MergedDictionaries>

        <!--  BRUSHES AND COLORS  -->
        <ResourceDictionary Source="Brushes/ColorStyles.xaml" />

    </ResourceDictionary.MergedDictionaries>
</ResourceDictionary>

変更の理由:リソース ディクショナリの現在の編成はひどく、変更する必要があります (オブジェクトを複数回作成しているため)。「Skin」フォルダーに 1 つのリソース ディクショナリを配置し、次に app.xaml で呼び出される ResourceLibrary.xaml ファイルにすべてマージされる残りのスタイル ディクショナリを整理するためのサブフォルダーを作成したいと考えていました。

私が試したこと: はい、上記のリンクのソリューションを使用しようとしました:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Skin/ResourceLibrary.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <!-- Dummy Style, anything you won't use goes -->
        <Style TargetType="{x:Type Rectangle}" />
    </ResourceDictionary>
</Application.Resources>

しかし、ダミーのスタイル行で次のエラーが発生します。

エラー 2 プロパティ要素を要素のコンテンツの途中に配置することはできません。コンテンツの前後に配置する必要があります。

コードを次のように変更すると、lisp コメントのおかげで上記のエラーが解消されました。

<Application.Resources>
    <ResourceDictionary>
        <!--Global View Model Locator-->
        <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />

        <!-- Dummy Style, anything you won't use goes -->
        <Style TargetType="{x:Type Rectangle}" />

        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Skin/ResourceLibrary.xaml"></ResourceDictionary>             
            <ResourceDictionary Source="Skin/Brushes/ColorStyles.xaml" />
            <ResourceDictionary Source="Skin/NamedStyles/AlertStyles.xaml" />

        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>               
</Application.Resources>

しかし、リソース ライブラリはまだ呼び出されていません。

また、すべてのファイル パスを変更して URI をパックしようとしましたが、それでも問題は解決しませんでした。

resourceLibrary.xaml と他のリソース ディクショナリを別のクラス ライブラリ プロジェクトに移動しようとしました (上記と同じフォルダー構造とファイルを使用)。次に、次の URI を使用しましたが、ResourceLibrary.xaml ファイルで宣言されたリソースにアクセスできません。

<ResourceDictionary Source="pack://application:,,,/FTC.Style;component/ResourceLibrary.xaml" />

ただし、上記の UIR 形式を使用して各リソース ディクショナリを App.Xaml ファイルに追加すると、リソースを使用できるようになります。

エラーはなくなりましたが、ResourceLibrary.xaml ファイルのマージされたディクショナリの一部であるリソースをまだ使用できません。このアプローチを使用する必要があるかどうかについては、dowhilefor のコメントに同意する傾向がありますが、この問題に対する最も一般的な解決策 (この投稿の上部にあるリンクを参照) が機能していない可能性があるため、これを理解したいと考えています。この解決策は他の誰かを助けることができます。

質問: ResourceLibrary.xaml ファイルが無視されるのはなぜですか?

4

3 に答える 3

28

私は MergedDictionaries に大きな問題を抱えており、あなたの問題も同じだと思います。私は自分の ResourceDictionaries を適切に整理したいと考えています。つまり、たとえば個別の Buttons.xaml、TextBoxes.xaml、Colors.xaml などがあるということです。私はそれらを Theme.xaml にマージします。多くの場合、すべてのスタイルは個別のアセンブリに含まれています (テーマを簡単に切り替えることができるようにするため)。私の ApplicationResources は次のとおりです。

<Application.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="/DefaultTheme;component/Theme.xaml" />
    </ResourceDictionary.MergedDictionaries>
    <Style TargetType="{x:Type Ellipse}"/>
  </ResourceDictionary>
</Application.Resources>

また、メイン アプリケーション アセンブリで定義された .xamls 内のすべての StaticResource が機能し、ダミー スタイルのおかげで既定のスタイルが機能します。 機能しないのは、 Theme 内の .xaml 間の StaticResourcesです。Colors.xaml の StaticResource を使用する Style を Buttons.xaml で定義すると、StaticResources と UnsetValue に関するエラーが発生します。Colors.xaml を Application MergedDictionaries に追加すると機能します。

ソリューション 0

組織を放棄します。すべてを 1 つの .xaml に入れます。MergedDictionaries にはすべての「問題」があるため、これが ResourceDictionaries の一般的な使用方法であると考えています (私にとってこれは悪夢です)。

解決策 1

テーマ内の xaml 間のすべての StaticResource 参照を DynamicResource に変更します。機能しますが、DynamicResources は StaticResources よりも「重い」ため、価格がかかります。

解決策 2

別の .xaml からの StaticResources を使用するすべてのテーマ .xaml で、この別の ResourceDictionary を MergedDictionaries に追加します。これは、Buttons.xaml、TextBoxes.xaml などの MergedDictionaries に Colors.xaml があることを意味します。これにより、Colors ResourceDictionary が複数のコピーでメモリに格納されます。それを避けるために、SharedResourceDictionaryを調べることをお勧めします。

解決策 3

さまざまな ResourceDictionaries セットアップ、さまざまな入れ子によって、私は理論を思いつきました:

上記の同じ .xaml またはこの ResourceDictionary の MergedDictionaries で StaticResource が見つからない場合は、他の最上位の MergedDictionariesで検索されます。

ApplicationResources に .xaml を 1 つだけ追加することをお勧めしますが、通常は 2 つの .xaml を使用することになります。テーマにあるすべての .xaml を ApplicationResources に追加する必要はありません。たとえば、Controls.xaml (任意の種類の MergedDictionaries ネストを使用しますが、Controls.xaml の辞書間の相互参照は許可されません) と Common.xaml です。これには、コントロールのすべての共通リソースが含まれています。Common.xaml のネストも許可されていますが、相互参照は許可されていない場合、Colors.xaml と、Colors を StaticResources として使用する Brushes.xaml を別々にすることはできません。その場合、Application MergedDictionaries に 3 つの .xaml を追加する必要があります。

現在、私は常に3番目のソリューションを使用していますが、それが完璧だとは考えておらず、より良い方法があるかどうかを知りたいと思っています. あなたが私の問題と同じ問題として説明したことを正しく解釈したことを願っています。

于 2013-06-13T09:14:25.230 に答える
1

アプリケーションにテーマを導入する必要があり、まさにこれらの問題に直面しました。

簡単に言え ば、リソース ディクショナリは、App.xaml で他のリソース ディクショナリより前にある場合、他のリソース ディクショナリを「参照」できます。App.xaml ではないファイルで MergedDictiories を使用しようとすると、リソース ディクショナリは互いに "認識" しません。

Generic.xaml の既定のリソースの場合: App.xaml で定義されたリソース、または App.xaml からマージされた辞書を DynamicResource としてのみ使用できます。Generic.xaml で定義されたリソースを StaticResource として使用できますが、スタイルが Generic.xaml 自体で定義されており、Generic.xaml 内のマージされたディクショナリで定義されていない場合に限ります。

完全な回答については、この問題に関するブログに詳細な投稿があります

私の提案する解決策: 必要な XAML 階層を作成し、ファイルを.txaml拡張子のフォルダーに配置します。ビルド前のイベントとして実行され、.txaml ファイルを 1 つの長い .XAML ファイルにマージする小さな単純なプログラム (以下の GitHub で提供) を作成しました。

これにより、WPF の制限なしで、必要に応じてリソース フォルダーとファイルを構造化できます。StaticResource とデザイナーは常に機能します。これは、1 つの長い Generic.xaml だけでなく、複数のファイルに CustomControl スタイルを含めることができる唯一のソリューションです。

これにより、複数の XAML ファイルが作成するパフォーマンスの問題も解決されます。

GitHub の Xaml マージ プログラム

于 2017-01-01T21:57:32.130 に答える