スキンの変更が必要な一部のアイテムがDynamicResourceExtentionタイプの値をサポートしていない場合に、WPFアプリケーションの動的スキニングを有効にするための最良の方法は何ですか?特に、私たちの問題は、ConverterParametersがStaticResourceExtentionsを必要とすることです。
VisualStudio2008とWPF3.5を使用したConverterParametersの状況は次のとおりです。
値とパラメーターを受け取り、それらの積を返すだけのカスタムコンバーターがあります。非常にシンプルで問題なく動作し、ウィンドウ要素のサイズの設定など、さまざまなタスクに使用します。たとえば、「Source = {x:Static SystemParameters.PrimaryScreenHeight}」の値と「0.1」のパラメータを渡すと、要素の高さを画面の高さの正確に1/10に設定できます。
Height="{Binding Source={x:Static SystemParameters.PrimaryScreenHeight},
Converter={StaticResource PctConverter},
ConverterParameter=0.1}"
ここで、PctConverterはカスタムコンバーターへのリソース参照です。問題ありません。
次に、ConverterParameterを抽出し、それを別のリソースに配置することで、アプリケーションを動的にスキンします。たとえば、要素の高さを一部のスキンでは画面の高さの0.1にし、他のスキンでは画面の高さの0.25にします。最初は、ConverterParameterをDynamicResourceに設定するだけだと思っていましたが、これはサポートされていないため、次のようにStaticResourceExtensionを使用して設定する必要があります。
Height="{Binding Source={x:Static SystemParameters.PrimaryScreenHeight},
Converter={StaticResource PctConverter},
ConverterParameter={StaticResource OurElementHeightParameter}}"
ここで、OurElementHeightParameterは、別のResourceDictionary(MainResource.xamlと呼びます)で次のように定義されています。
<sys:Double x:Key="OurElementHeightParameter">0.1</sys:Double>
(ここで、名前空間はxmlns:sys = "clr-namespace:System; assembly = mscorlib"として定義されています。)
CustomParameterの抽出に関する限り、これは正常に機能しますが、スキンをオンザフライで交換してConverterParameterを変更することはできません。
これをもう少し調べた後、特に次の記事
今必要だと思うのは、StaticResourceExtentionを取得し、リソースエイリアスを使用してその値をバックグラウンドで動的に設定することです。
これを実行するために、以前のOurElementHeightParameterリソースを次の2つのリソースに置き換えました
<sys:Double x:Key="SkinnedHeightRatio">0.1</sys:Double>
<StaticResourceExtension x:Key="OurElementHeightParameter" ResourceKey="SkinnedHeightRatio" />
これは正常に機能し、同じ結果を生成します。
それがうまくいったとき、SkinnedHeightRatioリソースを別のResourceDictionary(Skin.xamlと呼びます)に配置し、それを元のMainResource.xaml ResourceDictionaryとマージするだけで、必要な動的スキニングができると思いました。
ただし、別のResourceDictionaryに抽出するとすぐに、<sys:Single x:Key="SkinnedHeightRatio">0.1</sys:Single>
次のようなビルドエラーが発生します。
不明なビルドエラー、'インデックスが範囲外でした。負ではなく、コレクションのサイズよりも小さくする必要があります。
さらに奇妙なのは、上記の2つのリソースを同じResourceDictionaryに保持し、たとえば、それらの間に別のランダムなリソースを配置することによってそれらを分離する場合です。
<sys:Double x:Key="SkinnedHeightRatio">0.1</sys:Double>
<Thickness x:Key="SomeRandomResource" >5</Thickness>
<StaticResourceExtension x:Key="OurElementHeightParameter" ResourceKey="SkinnedHeightRatio" />
次に、OurElementHeightParameterは、その真上にあるSomeRandomResourceを指し、その2行上にあるResourceKeyプロパティ(SkinnedHeightRatio)で指定されたリソースではありません...この場合、コンバーターに渡されるパラメーターは、ThicknessSomeRandomResourceです。
すべて非常に紛らわしく、間違った木を完全に吠えているように思わせます。では、どこが間違っているのでしょうか。
問題を再現するアプリケーションの完全なコードが必要な場合は、投稿できます。
どんなポインタでも大歓迎です。