WPFのボタンをフラットデザインに変更する

WPFのボタンのスタイルをデフォルトのスタイルから変更して境界線のないフラットデザインへ変更します。

デフォルトのボタンコントロールを表示すると

  • 見た目がダサい(特にwindows7で)
  • Win7とWin10で見た目が著しく異なる
  • マウスオーバーしたときに青くなる
  • フォーカスが青く残る

と、割と嫌な動きをするので、上記を制御できるようにしたいと思います。以下がWin10での標準の見た目です。

f:id:Takachan:20171220001443p:plain

これを、以下のような、最近Webでよくある境界線のないタイプへ変更します。左側が通常状態で、右側がマウスが上に乗った時の表示になります。

f:id:Takachan:20171220002033p:plain

コード例

全てXAMLで表現します。適当な位置へボタンの見た目をフラット化する以下コードを置いておきます。

<Application.Resources>
    <!-- スタイルだけ抜粋 -->
    <Style x:Key="FlatButton" TargetType="Button" BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
        <!-- デフォルトのテーマを無効化 -->
        <Setter Property="OverridesDefaultStyle" Value="True" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border Background="{TemplateBinding Background}">
                        <ContentPresenter />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <!-- マウスオーバーした時に色を変える -->
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="true">
                <Setter Property="Background" Value="#CDD2D4"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Application.Resources>

実際に使用する箇所で以下コードを記述します。

<Button Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top"
        Width="130" Height="30"
        Style="{StaticResource FlatButton}">

    <!-- ボタンの中に表示する内容 -->
    <TextBlock Text="フラットスタイルのボタン" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Button>

また、ボタン上にマウスオーバーしたとき中のテキストに下線を以下のように作成することもでき、その場合

f:id:Takachan:20171220002733p:plain

追加で以下のXAMLをリソースへ追加し

<!-- 親要素がボタンならMouseOverした時だけ下線を表示する -->
<Style x:Key="UnderLine_In_Button" TargetType="TextBlock">
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor,
            AncestorType={x:Type Button}}, Path=IsMouseOver}" Value="true">
            <Setter Property="TextDecorations" Value="Underline"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

実際の利用側は以下のように記述します。

<Button Margin="10,10,10,0" HorizontalAlignment="Left" VerticalAlignment="Top"
        Width="90" Height="30" Style="{StaticResource FlatButton}">

    <!-- ボタンの中に表示する内容 -->
    <TextBlock Text="下線をつける" HorizontalAlignment="Center" 
               VerticalAlignment="Center" Style="{StaticResource UnderLine_In_Button}"/>
</Button>