WPFのDynamicなSolidColorBrushとDynamicなColor
WPFネタです。半日くらい悩んでいました
準備
App.xaml
抜粋
<Application.Resources> <Color x:Key="FillColor">#00ffff</Color> <SolidColorBrush x:Key="FillBrush" Color="{DynamicResource FillColor}"/> </Application.Resources>
MainWindow.xaml
<Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Rectangle Fill="{DynamicResource FillBrush}"/> <Rectangle Grid.Column="1"> <Rectangle.Fill> <SolidColorBrush Color="{DynamicResource FillColor}"/> </Rectangle.Fill> </Rectangle> <Button Grid.Row="1" Content="Red" Click="RedButton_Click"/> <Button Grid.Row="1" Grid.Column="1" Content="Green" Click="GreenButton_Click"/> </Grid>
MainWindow.xaml.cs
private void RedButton_Click(object sender, RoutedEventArgs e) { Application.Current.Resources["FillColor"] = Colors.Red; } private void GreenButton_Click(object sender, RoutedEventArgs e) { Application.Current.Resources["FillColor"] = Colors.Green; }
やっていること
- アプリケーションのリソースに
FillColor
というキーのColorとそのColorをDynamicResourceで参照しているFillBrush
を用意します - Windowの左側のRectangle.Fillには
FillBrush
をDynamicResourceで入れておきます - 右側のRectangle.FillにはXAMLでSolidColorBrushを書いて、そのColorを
{DynamicResource FillColor}
とします - ボタン二つは押したときに
FillColor
の色を変えるようにしています
動作結果
これを動かすと
MainWindow.xamlで{DynamicResource FillColor}
とした方だけが色が変わります。気持ち的には両方変わってほしいんですけどねぇ
ググるとStackOverflowに
というのが出てきて、SolidColorBrushはFrameworkElementでもFrameworkContentElementでもないからダメ、みたいな解答が書いてあります。サンプルのRectangleが両方色が変わらなかったら納得なんですけどね。ちなみに英語力皆無なので本当にそういうことが書いてあるのかは知りません
おまけ
App.xamlの定義をMainWindow.xamlに持ってきて同じようなことをしてみます
MainWindow.xaml
<Window.Resources> <Color x:Key="FillColor">#00ffff</Color> <SolidColorBrush x:Key="FillBrush" Color="{DynamicResource FillColor}"/> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Rectangle Fill="{DynamicResource FillBrush}"/> <Rectangle Grid.Column="1"> <Rectangle.Fill> <SolidColorBrush Color="{DynamicResource FillColor}"/> </Rectangle.Fill> </Rectangle> <Button Grid.Row="1" Content="Red" Click="RedButton_Click"/> <Button Grid.Row="1" Grid.Column="1" Content="Green" Click="GreenButton_Click"/> </Grid>
MainWindow.xaml.cs
private void RedButton_Click(object sender, RoutedEventArgs e) { Resources["FillColor"] = Colors.Red; } private void GreenButton_Click(object sender, RoutedEventArgs e) { Resources["FillColor"] = Colors.Green; }
結果
両方変わるよぉぉぉ