11

私は、テーマにたくさんのブラシを作成し、それらをカスタムコントロールで DynamicResource と一緒に使用するために、1日を無駄にしようとしました。私がしたことはこれです:

  • スタイルを含むテーマ generic.xaml を作成します (動作)
  • アプリケーションで使用されるブラシを含めるために、generic.xaml にマージする辞書を追加します (機能します)。
  • ブラシに ComponentResourceKey キーを持たせる (動作)
  • コントロールがブラシを静的リソースとして使用するようにします(機能)
  • コントロールが動的リソースとしてブラシを使用するようにします (DOESN'T WORK、リソース トレース ソースは次のように述べています: System.Windows.ResourceDictionary Warning: 9 : Resource not found; )
  • App.Resources に同じキーを持つブラシを動的に追加します (動的リソースで動作し、色を変更し、静的リソースでは動作しません)。

したがって、私の問題は、アプリケーションでプログラムで変更できるように、テーマでデフォルト値を定義する方法が見つからないことです。StaticResource はどのようにしてブラシを見つけ、DynamicResource は見つけられないのでしょうか?!

コンポーネント リソース キーをプロパティとして保持する静的クラスを作成し、それを xaml で {x:Static UI:ResourceScheme.ControlBackgroundKey} として使用することを追加する必要があります。私の問題はこれに似ているようです: ComponentResourceKey as DynamicResourceの問題は、静的プロパティキーをコンポーネントリソースキーのXAMLマークアップに置き換えても、まだ機能しません。

誰かがここで私を助けてくれますか? :(

4

3 に答える 3

7

ここに違いがあります。

StaticResource は読み込み時に読み込まれます。つまり、使用するリソース キーは、使用前に字句的に定義する必要があります。

そのため、カスタム コントロールの場合の静的リソースは、同じ generic.xaml ファイル内のコントロール定義の上にのみ定義する必要があります。したがって、ブラシを別の xaml に配置すると、静的リソースの場合は確実に機能しません。

これが、xaml 型の他のリソースがコンパイル時に何らかのインポートの形で同じファイルに含まれていない限り、ファイル内の静的リソースを使用できない理由です。これは単に、ファイル/コンポーネント/コントロールの実際の xaml に、使用する静的リソースの実際の参照が含まれている必要があることを意味します。

なぜDynamicResourceが機能しないのか疑問があります。おそらく、DynamicResourceはアプリケーションの(コントロールが使用されている)ResourceDictionaryのみを検索し、generic.xamlは検索しないからです。

100% 確実ではありませんが、カスタム コントロールを定義し、DynamicResource を使用する場合、リソースはアプリケーションのリソース ディクショナリまたはコントロールのリソース ディクショナリの親コンテナに存在する必要がありますが、generic.xaml に存在することはできません。 .

DynamicResource はコントロールのランタイムの論理ツリーでのみキーを検索するため、generic.xaml が Application.Resources に明示的に追加されない限り、generic.xaml にあるリソースが見つからないことがあります。

概要: StaticResource は、コンパイル時に同じファイル内でレキシカルに使用できる必要があります。リソースは Application.Resources ディクショナリで使用できます。論理ツリーで見つけることはできますが、コンパイル時には同じ dll または同じ generic.xaml でのみ見つけることができます。

DynamicResource は、実行時に Application.Resources およびコントロールの論理ツリーで検索される必要があります。

詳細については、リソースの概要を参照してください。

于 2010-08-21T10:03:05.903 に答える
7

最後にそれを修正しました。コンポーネント リソース キーの型が別のアセンブリにあることが問題全体の原因となっているようです。要約させてください:

  • ComponentResourceKeys を静的プロパティとして保持するリソース クラスがあります。リソース キーのコンストラクタで使用される型は、このクラスの型です。これは Resources アセンブリにあります。
  • 別のアセンブリである Controls アセンブリには、リソース クラスのプロパティをキーとして使用していくつかのブラシを定義するカスタム コントロールのテーマがあります: {x:Static Namespace:ResourceClass.ResourceKeyProperty}
  • 同じテーマで、コントロールのテンプレートはブラシを動的リソースとして使用します: {DynamicResource {x:Static Namespace:ResourceClass.ResourceKeyProperty}}
  • これらのコントロールを使用し、カスタム ブラシをアプリケーション リソースに動的に追加するアプリケーションもあります。これらのブラシには、テーマのブラシと同じキーがあります。

これの最終結果は次のとおりです。

  • コントロールは最初はブラシを使用しません
  • コントロールは、アプリケーション リソースに追加されたブラシを使用します。
  • テーマで StaticResource が使用されている場合、コントロールは最初にブラシを使用しますが、アプリケーション リソースは無視されます。

これに対する解決策は、リソース クラスをコントロール ライブラリに移動することのようです。

なぜこれが起こっているのかはまだわからないので、この質問は未解決のままです。わずかに変更されたとしても、最初のシナリオで機能しないのはなぜですか?

于 2010-08-21T12:27:58.833 に答える
2

問題を再現して、問題が解決しない理由についていくつかの理論をテストしようとしましたが、問題を再現できませんでした。セットアップは機能しているようです。

したがって、解決策を説明する代わりに、動作しない再現セットアップについて説明します。

ソリューション

対象フレームワーク: 4.6

プロジェクト

  • コントロール
    • 参考文献
      • 資力
    • ファイル
      • テーマ.xaml
  • 資力
    • ファイル
      • Keys.cs
  • Wpfアプリケーション
    • 参考文献
      • コントロール
      • 資力
    • ファイル
      • MainWindow.xaml

ファイルの内容

テーマ.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:r="clr-namespace:Resources;assembly=Resources">
    <Color x:Key="{x:Static r:Keys.PrettyColor}">Red</Color>
    <SolidColorBrush x:Key="{x:Static r:Keys.PrettyBrush}" 
                     Color="{DynamicResource {x:Static r:Keys.PrettyColor}}" />
</ResourceDictionary>

Keys.cs

namespace Resources {
    using System.Windows;

    public static class Keys {
        public static readonly ComponentResourceKey PrettyBrush =
            new ComponentResourceKey(typeof(Keys), Ids.PrettyBrush);

        public static readonly ComponentResourceKey PrettyColor =
            new ComponentResourceKey(typeof(Keys), Ids.PrettyColor);
    }

    public static class Ids {
        public const string PrettyBrush = "PrettyBrush";
        public const string PrettyColor = "PrettyColor";
    }
}

MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:resources="clr-namespace:Resources;assembly=Resources"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Controls;component/Theme.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <Color x:Key="{x:Static resources:Keys.PrettyColor}">Blue</Color>
        </ResourceDictionary>
    </Window.Resources>
    <Border Background="{DynamicResource {x:Static resources:Keys.PrettyBrush}}" />
</Window>

怠惰な人のために、スクリーンショットを次に示します。

ここに画像の説明を入力

于 2015-12-20T14:58:26.823 に答える