【WPF】フラットデザインなボタンを作成

XAMLで下記のようにボタンを配置すると、OSの種類によって見た目が変わってきてしまいます。

<Button Content="Button1" Margin="20" Height="100"
        Background="#1570A6"
        Foreground="White"/>

特にWindows7ではボタンが中途半端に立体的に表示されるため、マウスオーバーとボタンダウン時の表示が絶望的にダサい・・・
Windows7での表示は次のようになります。

通常時

マウスオーバー

マウスダウン

今どきWindows7に対しては、そこまで考慮しなくてもよいのかもしれませんが、他のOSでも使えるので独自のボタンを実装してみましょう。

ボタン用のスタイル定義

ボタン用のスタイルを定義します。次のコードを「App.xaml」内の<Application.Resources>に記載します。
Buttonを使用するとWindows7では角に丸みが出てしまうため、ControlTemplate内ではGridを使用しています。このGridに対してMouseOverなどの各イベントでStoryboardを使用して色を変化させます。

<!--ボタンのデフォルトスタイル-->
<Style TargetType="Button" >
    <Setter Property="Background" Value="White" />
    <Setter Property="Foreground" Value="#FF056096" />
</Style>
<!--フラットボタン用のコントロールテンプレート-->
<ControlTemplate  x:Key="ButtonTemplate" TargetType="Button">
    <!--角の丸みを取りたいためGridを使用-->
    <Grid x:Name="MyButton" Background="{TemplateBinding Background}">
        <!--ボタンの枠線-->
        <Border x:Name="MyBorder" BorderBrush="#1570A6" BorderThickness="1"/>
        <!--ボタン内のコンテンツ(テキストなど)-->
        <ContentPresenter x:Name="Presenter"
                         HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                         VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                         Margin="5" />

        <!--各イベントで表示を変えたいためVisualStateManagerを使用する-->
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup Name="CommonStates">
                <!--通常時(これが無いとマウスが外れても表示が戻らない)-->
                <VisualState Name="Normal" />
                <!--マウスオーバー時-->
                <VisualState Name="MouseOver">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetName="MyButton"
                                       Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
                                       Duration="00:00:00.1"
                                       To="#1570A6" />
                        <ColorAnimation Storyboard.TargetName="Presenter"
                                       Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
                                       Duration="00:00:00.1"
                                       To="white" />
                    </Storyboard>
                </VisualState>
                <!--ボタン押下時-->
                <VisualState Name="Pressed">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetName="MyButton"
                                       Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
                                       Duration="00:00:00.1"
                                       To="#2580B6" />
                        <ColorAnimation Storyboard.TargetName="Presenter"
                                       Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
                                       Duration="00:00:00.1"
                                       To="white" />
                        <ThicknessAnimation Storyboard.TargetName="MyButton"
                                            Storyboard.TargetProperty="Margin"
                                            Duration="00:00:00.1"
                                            To="0,0,0,0" />
                    </Storyboard>
                </VisualState>
                <!--ボタン無効化時-->
                <VisualState Name="Disabled">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetName="MyBorder"
                                       Storyboard.TargetProperty="BorderBrush.(SolidColorBrush.Color)"
                                       To="Gray"/>
                        <ColorAnimation Storyboard.TargetName="Presenter"
                                       Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
                                       To="Gray"/>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</ControlTemplate>

使用方法

使用するには、各WindowのXAMLでButtonに対してTemplateを指定します。

<Button Content="Button1" Template="{StaticResource ButtonTemplate}" Margin="20" Height="100"/>

表示は次のようになります。

通常時

マウスオーバー

マウスダウン

プロジェクト全体は下記リンクからダウンロードできます。
※Visual Studio 2017で作成しています。

WpfFlatButton

シェアする

  • このエントリーをはてなブックマークに追加

フォローする