WPF で Style を BasedOn してもデザイナで反映されない
◆ BasedOn は StaticResource じゃなくて DynamicResource にしないとデザイナで継承されてない
◆ でも DynamicResource だと実行時にエラーでる
◆ でも DynamicResource だと実行時にエラーでる
WPF で BasedOn でスタイルを継承して 継承したスタイルを設定してもデザイナで反映されてませんでした
こんな Resources を用意します
適当な window に
継承元の
これはデザイナだけで 実行して実際のウィンドウをみてみるとちゃんとフォントサイズが大きくなります
背景色くらいなら実際に動かしたときにちゃんと色が出ていればいいのですけど フォントサイズの場合はバランスとか文字がはみ出たりとか あるのでデザイナの確認と実際に動かしたときが異なるとちょっと困ります
バグかなーと思って諦めていたのですが偶然解決方法を発見しました
BasedOn を StaticResource じゃなくて DynamicResource で指定します
Window が Style を指定するところは StaticResource でも大丈夫です
途中で変更することもなく動的にする意味が無いと思うのにどうしてこれで解決するのかはわかりません
x:key と BasedOn と TargetType の並び順がどうこうというのを見かけましたが 並びを変えても変わりなかったので属性の順で動きが変わることはなさそうです
App.xaml
StaticResource で継承したスタイルを inherit_style_static
DynamicResource で継承したスタイルを inerit_style_dynamic にしてます


背景色は反映されてるけど文字が小さいです

背景も文字もちゃんと反映されています

Style 指定を Dynamic にしても文字は小さく base_style が使われていません

背景も文字もちゃんと反映されています
Resources 内の BasedOn で DynamicResource は使えないみたいです
デザイナだと動いてるのに というかこうしないとデザイナは動かないのに……
めんどうですが デザイナで確認しながら XAML 書くときには DynamicResource で継承したものを Style に指定して 実行するときには StaticResource で継承したものに置き換えるということになりそうです
不便ー
Style の指定はどっちでも大丈夫です
ただし 実行時には StaticResource にしていないとエラーになるので App.xaml の 「BasedOn="{DynamicResource」 と 「BasedOn="{StaticResource」 をデザイナで確認するときとビルドする時ですぐに切り替えれる用にしておかないとだめです
VisualStudio ならビルド前にコマンド実行できそうな気がするから ビルド前に置換?
こんな Resources を用意します
<Application.Resources>
<Style TargetType="Window" x:Key="base_style">
<Setter Property="FontSize" Value="30"/>
</Style>
<Style TargetType="Window" x:Key="inherit_style" BasedOn="{StaticResource base_style}">
<Setter Property="Background" Value="Violet"/>
</Style>
</Application.Resources>
<Style TargetType="Window" x:Key="base_style">
<Setter Property="FontSize" Value="30"/>
</Style>
<Style TargetType="Window" x:Key="inherit_style" BasedOn="{StaticResource base_style}">
<Setter Property="Background" Value="Violet"/>
</Style>
</Application.Resources>
適当な window に
Style={StaticResource inherit_style}"
と指定すると背景色は反映されていますが フォントサイズが反映されません継承元の
Style={StaticResource base_style}"
と指定してみると フォントサイズは大きくなりますこれはデザイナだけで 実行して実際のウィンドウをみてみるとちゃんとフォントサイズが大きくなります
背景色くらいなら実際に動かしたときにちゃんと色が出ていればいいのですけど フォントサイズの場合はバランスとか文字がはみ出たりとか あるのでデザイナの確認と実際に動かしたときが異なるとちょっと困ります
バグかなーと思って諦めていたのですが偶然解決方法を発見しました
BasedOn を StaticResource じゃなくて DynamicResource で指定します
Window が Style を指定するところは StaticResource でも大丈夫です
途中で変更することもなく動的にする意味が無いと思うのにどうしてこれで解決するのかはわかりません
x:key と BasedOn と TargetType の並び順がどうこうというのを見かけましたが 並びを変えても変わりなかったので属性の順で動きが変わることはなさそうです
サンプル
スクショ付きのサンプルですApp.xaml
<Application.Resources>
<Style TargetType="Window" x:Key="base_style">
<Setter Property="Background" Value="Honeydew"/>
<Setter Property="FontSize" Value="30"/>
</Style>
<Style TargetType="Window" x:Key="inherit_style_static" BasedOn="{StaticResource base_style}">
<Setter Property="Background" Value="Ivory"/>
</Style>
<Style TargetType="Window" x:Key="inherit_style_dynamic" BasedOn="{DynamicResource base_style}">
<Setter Property="Background" Value="Ivory"/>
</Style>
</Application.Resources>
<Style TargetType="Window" x:Key="base_style">
<Setter Property="Background" Value="Honeydew"/>
<Setter Property="FontSize" Value="30"/>
</Style>
<Style TargetType="Window" x:Key="inherit_style_static" BasedOn="{StaticResource base_style}">
<Setter Property="Background" Value="Ivory"/>
</Style>
<Style TargetType="Window" x:Key="inherit_style_dynamic" BasedOn="{DynamicResource base_style}">
<Setter Property="Background" Value="Ivory"/>
</Style>
</Application.Resources>
StaticResource で継承したスタイルを inherit_style_static
DynamicResource で継承したスタイルを inerit_style_dynamic にしてます
Base
base_style を指定したとき
Static 継承+ Static Style
BasedOn も Style 指定も StaticResource
背景色は反映されてるけど文字が小さいです
Dynamic 継承+ Static Style
BasedOn を DynamicResource で Style 指定は StaticResource
背景も文字もちゃんと反映されています
Static 継承+ Dynamic Style
BasedOn は StaticResource で Style 指定を DynamicResource
Style 指定を Dynamic にしても文字は小さく base_style が使われていません
Dynamic 継承+Dynamic Style
BasedOn も Style 指定も DynamicResource
背景も文字もちゃんと反映されています
解決だと思ったら
全部 DynamicResource にして これでよしっ と思って そのまま実装終えていざ実行 というときに実行時エラーが起きました・・・Resources 内の BasedOn で DynamicResource は使えないみたいです
デザイナだと動いてるのに というかこうしないとデザイナは動かないのに……
めんどうですが デザイナで確認しながら XAML 書くときには DynamicResource で継承したものを Style に指定して 実行するときには StaticResource で継承したものに置き換えるということになりそうです
不便ー
まとめ
デザイナで反映させるには BasedOn だけ DynamicResource にする必要がありStyle の指定はどっちでも大丈夫です
ただし 実行時には StaticResource にしていないとエラーになるので App.xaml の 「BasedOn="{DynamicResource」 と 「BasedOn="{StaticResource」 をデザイナで確認するときとビルドする時ですぐに切り替えれる用にしておかないとだめです
VisualStudio ならビルド前にコマンド実行できそうな気がするから ビルド前に置換?