徒然電脳

日々のプログラミング(とその他)忘備録 このサイトは独自研究のみに基づきます マサカリ歓迎しますというかよろしくお願いします

WPFの簡単なまとめ Style編

1回:WPFの簡単なまとめ Resorce編 - 徒然電脳

リソースとスタイル

スタイルはリソースとの相性抜群!
というわけで今回はスタイルを忘備録

Style?

スタイルは以下のように使用できます。

MainWindow.xml

<Window x:Class="Style.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">
    <StackPanel>
        <StackPanel.Resources>
            <!-- Style -->
            <Style TargetType="Button">
                <Setter Property="Background" Value="Aqua"/>
                <Setter Property="FontFamily" Value="Comic Sans MS"/>
            </Style>
        </StackPanel.Resources>

        <Button Content="Button"/>
        <Button Content="YEAH"/>

    </StackPanel>
</Window>

まず、ResourceDictionaryがひとつ(マージしない)場合は省略できることを今更言っておきます。

Resource内にStyle要素を定義してあげます。そのTargetTypeプロパティで適応させたい要素名を指定。Style要素の中には「あるプロパティに値を設定させる」Setter要素を詰め込みます。今回はButtonのBackgroundプロパティにAqua、FontFamilyプロパティにComic Sans MSフォントを指定させるSetterを2つ用意して終わります。

実行結果を見てみましょう。
f:id:TempProg:20150704153042j:plain

はい。面白い水色背景に面白いフォントになりました。「Button要素自体には何も設定していないのにもかかわらず!」

Styleの有用性

前回のように外観を設定するのとStyleを使用するのとで大きく違うことがありますね。
・指定要素全てに適応させることができる。
・一度に複数指定することができる。

イメージとしてはHTMLに対するCSSみたいなものでしょうか。
Styleを使えばデザインの統一が図れそうです。

特定要素への設定

CSSといえば、HTMLのclassとかidで設定をして、特定の要素に対してのみ指定することも出来ました。もちろんWPFのスタイルも同じようなことができます。

MainWindow.xaml

<Window x:Class="Style.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">
    <StackPanel>
        <StackPanel.Resources>
            <Style TargetType="Button">
                <Setter Property="Background" Value="Aqua"/>
                <Setter Property="FontFamily" Value="Comic Sans MS"/>
            </Style>

            <!--x:Key指定-->
            <Style x:Key="special" TargetType="Button">
                <Setter Property="Background" Value="Red"/>
                <Setter Property="FontFamily" Value="Comic Sans MS"/>
                <Setter Property="FontSize" Value="25"/>
            </Style>
        </StackPanel.Resources>

        <Button Content="Button"/>
        <Button Content="YEAH"/>
        <Button Content="Hello" Style="{StaticResource special}" />
    </StackPanel>
</Window>

実行結果はどうなるでしょう
f:id:TempProg:20150704154304j:plain

なるほど。Styleの方でx:Keyを指定してあげれば、それを指定された要素にのみそのスタイルが適応されるようになります。Buttonの方でStyleプロパティにStaticResourceで指定してあげます。

継承

x:Keyを指定してあげたスタイルからFontFamilyに対するセッターを削除すると、フォントは「デフォルト」のものに戻ってしまいます。だからといって、いちいち指定するのも面倒です。そこで、Button全体に対するスタイルを継承する形を取ります。「継承」と言うとクラスの継承と混同しそうですが、おそらくこの場合は「取り込み」のほうが近いのかもしれません。(xamlは型ではなくインスタンスをつくるものなので)

MainWindow.xaml

<Window x:Class="Style.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">
    <StackPanel>
        <StackPanel.Resources>
            <Style TargetType="Button">
                <Setter Property="Background" Value="Aqua"/>
                <Setter Property="FontFamily" Value="Comic Sans MS"/>
            </Style>

            <!--BasedOnプロパティ-->
            <Style x:Key="special" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
                <Setter Property="Background" Value="Red"/>
                <Setter Property="FontSize" Value="25"/>
            </Style>
        </StackPanel.Resources>

        <Button Content="Button"/>
        <Button Content="YEAH"/>
        <Button Content="Hello" Style="{StaticResource special}" />
    </StackPanel>
</Window>

スタイルのBasedOnプロパティにこのような指定をしてあげればよいです。

トリガー

デフォルトのボタンでも、マウスオーバー時、クリック時など場合によってスタイルが変化することがあります。
これを設定するにはStyle.Triggersプロパティを設定します。

MainWindow.xaml

<Window x:Class="Style.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">
    <StackPanel>
        <StackPanel.Resources>
            <Style TargetType="Button">
                <Setter Property="Background" Value="Aqua"/>
                <Setter Property="FontFamily" Value="Comic Sans MS"/>
            </Style>

            <Style x:Key="special" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
                <Setter Property="Background" Value="Red"/>
                <Setter Property="FontSize" Value="25"/>
                
                <!-- Triggers -->
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="Beige"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </StackPanel.Resources>

        <Button Content="Button"/>
        <Button Content="YEAH"/>
        <Button Content="Hello" Style="{StaticResource special}" />
    </StackPanel>
</Window>

多分見た感じでわかるかと思います。
実行してみるとボタン上にマウスを置いてやると背景色が変わったのがわかります。この例では背景がRed、文字の大きさが25という設定をベースに、マウスオーバー時に背景をBeigeに変えるという動作をします。そのため、マウスオーバー時でも文字の大きさは25のまま固定です。


とりあえずこれでStyleは終わりー
ところで、嘘言ってるかもしれないのでどんどんいぢめてもらって構いません(╹◡╹)