トップ回答者
MergedDictionariesを使うとデフォルトのStyleが適用されない場合がある

質問
-
お世話になります
WPFで、コントロールごとのStyleを別ファイルで管理して、それらのStyleファイルを一括して参照できるようにしたいと考えています。しかし、実際に使用すると、VSのデザイナーでは正しくスタイルが適用されているように見えるのですが実行するとStyleが適用されない場合があります。明示的に指定するStyleは適用されるのですが暗黙で指定するStyleが適用されないようです。
回避方法などありましたらご教授いただけないでしょうか?
例えば、以下のようなStyleをコントロールごとに個別に作成して、
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style TargetType="TextBlock"> <Setter Property="Foreground" Value="Red" /> </Style> <Style x:Key="BlueText" TargetType="TextBlock"> <Setter Property="Foreground" Value="Blue" /> </Style> </ResourceDictionary>
以下のようなファイルにまとめて一括して参照できるようにします。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="TextBlockStyle.xaml" /> <ResourceDictionary Source="TextBoxStyle.xaml" /> <ResourceDictionary Source="ButtonStyle.xaml" /> <ResourceDictionary Source="...." /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary>
このファイルを、参照して以下のようなWindowを作成すると、デザイナ上では最初のテキストが赤、次のテキストが青と期待通りに表示されるのですが実行すると最初のテキストにスタイルが適用されていません。
個別のStyleファイルを直接読み込ませるとStyleは期待通りに適用されます。
<Window x:Class="NestMergetDictionaryTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Dictionary1.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Window.Resources> <Grid> <TextBlock Height="26" HorizontalAlignment="Left" Margin="84,116,0,0" Name="textBlock1" Text="Red Text" VerticalAlignment="Top" Width="153" /> <TextBlock Height="26" HorizontalAlignment="Left" Margin="84,148,0,0" Style="{StaticResource BlueText}" Name="textBlock2" Text="Blue Text" VerticalAlignment="Top" Width="153" /> </Grid> </Window>
以上、宜しくお願いします
回答
-
現象確認しました。確かにデザイナの表示と実行時で挙動が違いますね。
・・・そこはかとなくバグっぽいですねー(苦笑)で、とりあえずスタイルの適用ですが
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Dictionary1.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Window.Resources> <Grid> <TextBlock Height="26" HorizontalAlignment="Left" Margin="84,116,0,0" Style="{StaticResource {x:Type TextBlock}}" Name="textBlock1" Text="Red Text" VerticalAlignment="Top" Width="153" /> <TextBlock Height="26" HorizontalAlignment="Left" Margin="84,148,0,0" Style="{StaticResource BlueText}" Name="textBlock2" Text="Blue Text" VerticalAlignment="Top" Width="153" /> </Grid> </Window>
こんな感じで、Style="{StaticResource {x:Type TextBlock}}"とやってやると、TextBlockのデフォルトスタイルが適用されます。
・・・でもこれで指定できるって事は参照はできてるって事ですから、何もせんでも適用されるべきですよねぇ・・・やっぱりバグ臭いなぁ(笑)
以上、参考になれば幸いです。
-
>> 2段階で読み込ませるのをやめて、各ウィンドウの.xamlで直接TextBlockStyle.xamlなどを参照した方が良さそうですね。Styleファイルが多くて多少面倒ではあるのですが、、、
直接の解決にはならないですが、複数のWindowで同じリソース定義を用いるのが目的でしたら、App.xamlのリソースで定義してやれば同一プロセス内の全Windowに同じリソースが適用されますよ。
リソース定義はアプリ内共通のものはApp.xamlに記述して、Window毎の個別のものだけWindow側に記述するのが最適かと思います。
すべての返信
-
現象確認しました。確かにデザイナの表示と実行時で挙動が違いますね。
・・・そこはかとなくバグっぽいですねー(苦笑)で、とりあえずスタイルの適用ですが
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Dictionary1.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Window.Resources> <Grid> <TextBlock Height="26" HorizontalAlignment="Left" Margin="84,116,0,0" Style="{StaticResource {x:Type TextBlock}}" Name="textBlock1" Text="Red Text" VerticalAlignment="Top" Width="153" /> <TextBlock Height="26" HorizontalAlignment="Left" Margin="84,148,0,0" Style="{StaticResource BlueText}" Name="textBlock2" Text="Blue Text" VerticalAlignment="Top" Width="153" /> </Grid> </Window>
こんな感じで、Style="{StaticResource {x:Type TextBlock}}"とやってやると、TextBlockのデフォルトスタイルが適用されます。
・・・でもこれで指定できるって事は参照はできてるって事ですから、何もせんでも適用されるべきですよねぇ・・・やっぱりバグ臭いなぁ(笑)
以上、参考になれば幸いです。
-
>> 2段階で読み込ませるのをやめて、各ウィンドウの.xamlで直接TextBlockStyle.xamlなどを参照した方が良さそうですね。Styleファイルが多くて多少面倒ではあるのですが、、、
直接の解決にはならないですが、複数のWindowで同じリソース定義を用いるのが目的でしたら、App.xamlのリソースで定義してやれば同一プロセス内の全Windowに同じリソースが適用されますよ。
リソース定義はアプリ内共通のものはApp.xamlに記述して、Window毎の個別のものだけWindow側に記述するのが最適かと思います。