none
MergedDictionariesを使うとデフォルトのStyleが適用されない場合がある RRS feed

  • 質問

  • お世話になります

    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>
    以上、宜しくお願いします

    2012年9月11日 2:45

回答

  • 現象確認しました。確かにデザイナの表示と実行時で挙動が違いますね。
    ・・・そこはかとなくバグっぽいですねー(苦笑)

    で、とりあえずスタイルの適用ですが

    <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のデフォルトスタイルが適用されます。
    ・・・でもこれで指定できるって事は参照はできてるって事ですから、何もせんでも適用されるべきですよねぇ・・・やっぱりバグ臭いなぁ(笑)

    以上、参考になれば幸いです。

    • 回答の候補に設定 佐伯玲 2012年9月18日 8:00
    • 回答としてマーク 佐伯玲 2012年9月21日 5:24
    2012年9月11日 4:57
  • >> 2段階で読み込ませるのをやめて、各ウィンドウの.xamlで直接TextBlockStyle.xamlなどを参照した方が良さそうですね。Styleファイルが多くて多少面倒ではあるのですが、、、

    直接の解決にはならないですが、複数のWindowで同じリソース定義を用いるのが目的でしたら、App.xamlのリソースで定義してやれば同一プロセス内の全Windowに同じリソースが適用されますよ。
    リソース定義はアプリ内共通のものはApp.xamlに記述して、Window毎の個別のものだけWindow側に記述するのが最適かと思います。

    • 回答の候補に設定 佐伯玲 2012年9月18日 8:00
    • 回答としてマーク 佐伯玲 2012年9月21日 5:24
    2012年9月12日 5:33

すべての返信

  • 現象確認しました。確かにデザイナの表示と実行時で挙動が違いますね。
    ・・・そこはかとなくバグっぽいですねー(苦笑)

    で、とりあえずスタイルの適用ですが

    <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のデフォルトスタイルが適用されます。
    ・・・でもこれで指定できるって事は参照はできてるって事ですから、何もせんでも適用されるべきですよねぇ・・・やっぱりバグ臭いなぁ(笑)

    以上、参考になれば幸いです。

    • 回答の候補に設定 佐伯玲 2012年9月18日 8:00
    • 回答としてマーク 佐伯玲 2012年9月21日 5:24
    2012年9月11日 4:57
  • みっと様

    早速の返信ありがとうございます。このような使い方では暗黙のスタイルを使うのは現状難しいのでしょうか、、、

    2段階で読み込ませるのをやめて、各ウィンドウの.xamlで直接TextBlockStyle.xamlなどを参照した方が良さそうですね。Styleファイルが多くて多少面倒ではあるのですが、、、

    2012年9月11日 10:10
  • >> 2段階で読み込ませるのをやめて、各ウィンドウの.xamlで直接TextBlockStyle.xamlなどを参照した方が良さそうですね。Styleファイルが多くて多少面倒ではあるのですが、、、

    直接の解決にはならないですが、複数のWindowで同じリソース定義を用いるのが目的でしたら、App.xamlのリソースで定義してやれば同一プロセス内の全Windowに同じリソースが適用されますよ。
    リソース定義はアプリ内共通のものはApp.xamlに記述して、Window毎の個別のものだけWindow側に記述するのが最適かと思います。

    • 回答の候補に設定 佐伯玲 2012年9月18日 8:00
    • 回答としてマーク 佐伯玲 2012年9月21日 5:24
    2012年9月12日 5:33
  • こんにちは、rv_kn さん
    フォーラムオペレータの佐伯 玲 です。

    みっと さんの返信が参考になる思われましたので
    勝手ながら私のほうで「回答としてマーク」をさせていただきました。

    もし追加の情報などございましたら引き続きこちらのスレッドをご使用くださいませ。

    今後ともMSDNフォーラムを宜しくお願い致します。
    __________________________
    日本マイクロソフト株式会社 フォーラム オペレーター 佐伯 玲

    2012年9月21日 5:24