質問

WPFアプリケーションとは別のdllにBaseSkinと複数のUserSkinがあります。

アプリケーションを使用しているユーザーに応じて、ベーススキンとユーザースキンの1つがリソースディクショナリにマージされ、アプリケーションが使用するためにロードされます。

私が目指しているのは、BaseSkinファイルでスタイルを指定し、特定のUserSkinファイルでスタイルをオーバーライドして、必要なプロパティを変更できるようにすることです。

次のようにBasedOn属性を使用してこれを達成できることを知っています:

ベース:

<Style x:Key="ButtonBg" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="Green"/>
</Style>

ユーザー:

<Style x:Key="CustomButtonBg" TargetType="{x:Type Button}" BasedOn="{StaticResource ButtonBg}">
    <Setter Property="Background" Value="Blue"/>
</Style>

問題は、要素が実際には実装されていない可能性のあるCustomButtonBgのStyleを持つ必要があることです。両方のスタイルで同じキー(ButtonBg)を使用する方法はありますか?それらがマージされると、アプリケーションは最初にUserでButtonBgという名前のスタイルを探し、存在しない場合はbaseのスタイルを使用しますか?

BaseSkinファイルを指すようにBasedOn属性でアセンブリ名を指定できれば、同じキーを指定したときに名前付けエラーを回避できると考えていましたが、その方法は見つかりません。他のオプションは、何も変更されない場合でも各スタイルの実装を強制するか、スキンをプログラムでチェックしますが、これらは最後の手段です。

役に立ちましたか?

解決

リソースルックアップロジックを利用することができます。 WPFがキーでリソースを見つけようとするとき、最初に現在の要素の ResourceDictionary を調べ、次にその親、次にその親などを調べます。

ユーザーに条件付きだと言ったので、元のベースが Applicationにある間に Window レベルで ResourceDictionary にマージされる可能性がありますレベル。

編集:より良い情報があります。 MSDNのマージされた辞書から:

  

マージされた辞書の動作

     

マージされたディクショナリ内のリソースは、リソースルックアップスコープ内の場所を占有します。リソースルックアップスコープは、マージされるメインリソースディクショナリのスコープの直後です。リソースキーは個々のディクショナリ内で一意である必要がありますが、キーはマージされたディクショナリのセットに複数回存在できます。この場合、返されるリソースは、MergedDictionariesコレクションで順番に見つかった最後の辞書から取得されます。 MergedDictionariesコレクションがXAMLで定義されている場合、コレクション内のマージされた辞書の順序は、マークアップで提供される要素の順序です。キーがプライマリ辞書およびマージされた辞書でも定義されている場合、返されるリソースはプライマリ辞書から取得されます。これらのスコープ規則は、静的リソース参照と動的リソース参照の両方に等しく適用されます。

つまり、ベーススキンを別の ResourceDictionary で定義し、別の ResourceDictionary にマージできます。後者のユーザースキンを使用すると、最初に検出されます。それ以外の場合は、Baseを含むマージされたディクショナリにドリルダウンし続けます。ユーザー辞書のそれぞれがベース辞書をマージでき、ユーザー辞書を両方ではなくアプリにロードするだけです。

他のヒント

BaseにBaseButtonBgという名前を付けるだけで、ユーザーベースのResourceDictionaryをマージしない場合は、次のものを含む一般的なものをマージします。

<Style x:Key="ButtonBg" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonBg}"/>
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top