アプリケーションにスキニングを実装しました。アプリケーションは、スキン固有のリソースディクショナリにある色を使用するBrushes.xamlリソースディクショナリをロードします。そのため、選択したスキンに応じて1つのColor.xamlのみがロードされます。
スキン固有のColor.xaml
<Color x:Key="TextBoxBackgroundColor">#C4AF8D</Color>
<Color x:Key="TextBoxForegroundColor">#6B4E2C</Color>
<Color x:Key="ToolBarButtonForegroundColor">#6B4E2C</Color>
Brushes.xaml:
<SolidColorBrush
x:Key="TextBoxBackground"
Color="{DynamicResource TextBoxBackgroundColor}" />
<SolidColorBrush
x:Key="TextBoxForeground"
Color="{DynamicResource TextBoxForegroundColor}" />
ご覧のとおり、複数の色(TextBoxForegroundColorとToolBarButtonForegroundColor)は同じです。特に使用される色が16進値で認識できないため、ますます混乱しているので、これを回避したいと思います。両方の色を1つにマージすることをお勧めしますが、TextBoxForegroundColorがToolBarButtonForegroundColorと異なるスキンがあります。
私がやりたいのは次のようなものです:
<Color x:Key="DarkBrown">#C4AF8D</Color>
<Color x:Key="TextBoxBackgroundColor" Color={StaticResource DarkBrown} />
<Color x:Key="ToolBarButtonForegroundColor" Color={StaticResource DarkBrown} />
これはXamlではまったく可能ですか?方法が見つかりませんでした。
この?
<Color x:Key="DarkBrown">#C4AF8D</Color>
<DynamicResource x:Key="TextBoxBackgroundColor" ResourceKey="DarkBrown"/>
<DynamicResource x:Key="ToolBarButtonForegroundColor" ResourceKey="DarkBrown"/>
より高度な使用例と複数レベルのエイリアシングについては、 this answer を参照してください。
Brushes.xamlをスキン固有にするだけではどうですか?次に、これがあります:
<Color x:Key="DarkBrown">#C4AF8D</Color>
<SolidColorBrush x:Key="TextBoxBackgroundBrush" Color={StaticResource DarkBrown} />
<SolidColorBrush x:Key="ToolBarButtonForegroundBrush" Color={StaticResource DarkBrown} />
スキン固有のブラシを作成することのもう1つのポイントは、ToolBarButtonForegroundBrush
をあるスキンでは無地のブラシに、別のスキンではグラデーションブラシにしたいという状況があることです。
H.B.の答えは非常に興味深いものであり、この質問が何を求めているのかを正確にしたいので、私はかなりそれをいじっていました。
私が気づいたのは、WPF 3.5ではDynamicResourceの使用が機能しないことです。つまり、実行時に例外がスローされます(Amentiが語っています)。ただし、共有する色を参照している色を作成する場合、StaticResourceは、WPF 3.5とWPF 4.0の両方で機能します。
つまり、このxamlはWPF 3.5とWPF 4.0の両方で機能します。
<Window
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
x:Class="ColorsReferencingColors.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640"
Height="480"
>
<Window.Resources>
<Color x:Key="DarkBlue">DarkBlue</Color>
<StaticResource x:Key="EllipseBackgroundColor" ResourceKey="DarkBlue"/>
<SolidColorBrush
x:Key="ellipseFillBrush"
Color="{DynamicResource EllipseBackgroundColor}"
/>
</Window.Resources>
<Grid>
<StackPanel Margin="25">
<Ellipse
Width="200"
Height="200"
Fill="{DynamicResource ellipseFillBrush}"
/>
</StackPanel>
</Grid>
</Window>
もう1つ言及しなければならないことは、このアプローチは、そこにいるデザイナー(つまり、Visual Studio 2008および2010デザイナー、Blend 3および4デザイナー)に大混乱をもたらすことです。これは、Kaxaml 1.7がH.B.のxamlを好まなかったのと同じ理由であると推測します(H.B.の回答のコメントストリームをフォローしている場合)。
しかし、単純なテストケースでは設計者を破壊しますが、私が日々の仕事で取り組んでいる大規模なアプリケーションの設計面を破壊するようには見えません。普通じゃない!つまり、デザイナーでまだ機能していることに関心がある場合は、とにかくこの方法を試してみてください。
ColorにはColorプロパティがないため、その最後の部分は不可能です。
A Colorには、R、G、B、およびAプロパティがあります。したがって、リソースとして4バイトを作成できます。
<ResourceDictionary xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;Assembly=mscorlib">
<sys:Byte x:Key="r">#23</sys:Byte>
<sys:Byte x:Key="g">#45</sys:Byte>
<sys:Byte x:Key="b">#67</sys:Byte>
<sys:Byte x:Key="a">#FF</sys:Byte>
<Color x:Key="c1" R="{StaticResource r}"
G="{StaticResource g}"
B="{StaticResource b}"
A="{StaticResource a}"/>
<Color x:Key="c2" R="{StaticResource r}"
G="{StaticResource g}"
B="{StaticResource b}"
A="{StaticResource a}"/>
</ResourceDictionary>
それでもあなたが好むかもしれないものではありませんが、それは動作するはずです。