WPF シンプルなCheckBoxのスタイルを作る
はじめに
ここでは、シンプルかつFlatなUIデザインで使えそうなチェックボックスのスタイルを作成します。スタイルの変更方法については以下を参考にしています。
CheckBox のスタイルとテンプレート - WPF .NET Framework | Microsoft Docs
丸いスタイル1
イメージ
作成するスタイルは以下の通りです。
ソースコード
ソースコードは以下の通りです。
<Window x:Class="Checkbox1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Checkbox1" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Title="MainWindow" Width="800" Height="450" mc:Ignorable="d"> <Window.Resources> <!-- チェックボックスのサイズや見た目 --> <Thickness x:Key="CheckBorderThickness">0.0</Thickness> <Thickness x:Key="UnCheckBorderThickness">2.0</Thickness> <CornerRadius x:Key="CheckBoxCornerRadius">20.0</CornerRadius> <!-- チェックボックスの色 --> <SolidColorBrush x:Key="CheckedBorderColor">#0984e3</SolidColorBrush> <SolidColorBrush x:Key="CheckedBackColor">#0984e3</SolidColorBrush> <SolidColorBrush x:Key="UnCheckedBorderColor">#0984e3</SolidColorBrush> <SolidColorBrush x:Key="UnCheckedBackColor">#ffffff</SolidColorBrush> <SolidColorBrush x:Key="CheckMarkColor">#ffffff</SolidColorBrush> <SolidColorBrush x:Key="IndeterminateMarkColor">#d63031</SolidColorBrush> <!-- チェックボックスのスタイル --> <Style x:Key="MyCheckBox" TargetType="{x:Type CheckBox}"> <Setter Property="SnapsToDevicePixels" Value="true" /> <Setter Property="OverridesDefaultStyle" Value="true" /> <Setter Property="FocusVisualStyle" Value="{DynamicResource CheckBoxFocusVisual}" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type CheckBox}"> <BulletDecorator> <BulletDecorator.Bullet> <Grid Width="20.0" Height="20.0"> <!-- チェックボックス --> <Border x:Name="CheckBoxBorder" Background="{StaticResource UnCheckedBackColor}" BorderBrush="{StaticResource UnCheckedBorderColor}" BorderThickness="{StaticResource UnCheckBorderThickness}" CornerRadius="{StaticResource CheckBoxCornerRadius}" /> <!-- チェックマーク --> <Path x:Name="CheckMark" Margin="4" Data="M0 4 L3.5 7 8 2" SnapsToDevicePixels="False" Stretch="Uniform" Stroke="{StaticResource CheckMarkColor}" StrokeThickness="2.5" Visibility="Collapsed" /> <!-- 不定時のチェックマーク --> <Path x:Name="IndeterminateMark" Margin="4" Data="M 0 7 L 7 0" SnapsToDevicePixels="False" Stretch="Uniform" Stroke="{StaticResource IndeterminateMarkColor}" StrokeThickness="2.5" Visibility="Collapsed" /> </Grid> </BulletDecorator.Bullet> <ContentPresenter Margin="4,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" /> </BulletDecorator> <ControlTemplate.Triggers> <!-- チェック時のスタイル --> <Trigger Property="IsChecked" Value="True"> <Setter TargetName="CheckMark" Property="Visibility" Value="Visible" /> <Setter TargetName="CheckBoxBorder" Property="Background" Value="{StaticResource CheckedBackColor}" /> <Setter TargetName="CheckBoxBorder" Property="BorderThickness" Value="{StaticResource CheckBorderThickness}" /> </Trigger> <!-- 不定時のスタイル --> <Trigger Property="IsChecked" Value="{x:Null}"> <Setter TargetName="IndeterminateMark" Property="Visibility" Value="Visible" /> </Trigger> <!-- 未チェック状態でマウスオーバー時のスタイル --> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsMouseOver" Value="True" /> <Condition Property="IsChecked" Value="False" /> </MultiTrigger.Conditions> <Setter TargetName="CheckMark" Property="Visibility" Value="Visible" /> <Setter TargetName="CheckMark" Property="Stroke" Value="{StaticResource CheckedBackColor}" /> <Setter TargetName="CheckMark" Property="Opacity" Value="0.2" /> </MultiTrigger> <!-- チェック状態でマウスオーバー時のスタイル --> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsMouseOver" Value="True" /> <Condition Property="IsChecked" Value="True" /> </MultiTrigger.Conditions> <Setter TargetName="CheckBoxBorder" Property="Opacity" Value="0.8" /> </MultiTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <Grid HorizontalAlignment="Center" VerticalAlignment="Center"> <StackPanel> <!-- スタイルの適用例 --> <CheckBox Content="未チェック状態" IsChecked="False" Style="{StaticResource MyCheckBox}" /> <Label Height="10" /> <CheckBox Content="チェック状態" IsChecked="True" Style="{StaticResource MyCheckBox}" /> <Label Height="10" /> <CheckBox Content="不定状態" IsChecked="{x:Null}" Style="{StaticResource MyCheckBox}" /> </StackPanel> </Grid> </Window>
解説
サイズや色の定義
まず主なパラメータをリソースとして定義します。後から異なるスタイルに変更した例も紹介しますが、こうすることでスムーズにスタイルを変更することができます(目的のスタイルが決まった場合は直接入力しても良いと思います)。
色選びについては以下のサイトが参考になるのでおすすめです。
Flat UI Colors 2 - 14 Color Palettes, 280 colors 🎨
<Window.Resources> <!-- チェックボックスのサイズや見た目 --> <Thickness x:Key="CheckBorderThickness">0.0</Thickness> <Thickness x:Key="UnCheckBorderThickness">2.0</Thickness> <CornerRadius x:Key="CheckBoxCornerRadius">20.0</CornerRadius> <!-- チェックボックスの色 --> <SolidColorBrush x:Key="CheckedBorderColor">#0984e3</SolidColorBrush> <SolidColorBrush x:Key="CheckedBackColor">#0984e3</SolidColorBrush> <SolidColorBrush x:Key="UnCheckedBorderColor">#0984e3</SolidColorBrush> <SolidColorBrush x:Key="UnCheckedBackColor">#ffffff</SolidColorBrush> <SolidColorBrush x:Key="CheckMarkColor">#ffffff</SolidColorBrush> <SolidColorBrush x:Key="IndeterminateMarkColor">#d63031</SolidColorBrush>
チェックボックスの背景、チェックマークの定義
Grid内に、チェックボックスの背景用のBorder、チェックマーク用のPathを作成します。
ここではチェック状態と不定状態の2つのPathを定義します。このPathの使い方は結構複雑なので、ここでは詳しく説明しません。機会があれば、別記事で取り上げようと思います。
ポイントとしては、Stretch="Uniform"
とすることで親であるGridのWight、Heightが変化した場合にチェックマークのサイズも変更されるようにしています。そのためサイズ調整したい場合はGridのWight、Heightだけ調整すればよいです。
<Grid Width="20.0" Height="20.0"> <!-- チェックボックス --> <Border x:Name="CheckBoxBorder" Background="{StaticResource UnCheckedBackColor}" BorderBrush="{StaticResource UnCheckedBorderColor}" BorderThickness="{StaticResource UnCheckBorderThickness}" CornerRadius="{StaticResource CheckBoxCornerRadius}" /> <!-- チェックマーク --> <Path x:Name="CheckMark" Margin="4" Data="M0 4 L3.5 7 8 2" SnapsToDevicePixels="False" Stretch="Uniform" Stroke="{StaticResource CheckMarkColor}" StrokeThickness="2.5" Visibility="Collapsed" /> <!-- 不定時のチェックマーク --> <Path x:Name="IndeterminateMark" Margin="4" Data="M 0 7 L 7 0" SnapsToDevicePixels="False" Stretch="Uniform" Stroke="{StaticResource IndeterminateMarkColor}" StrokeThickness="2.5" Visibility="Collapsed" /> </Grid>
チェックマークを表示させる
Triggerを利用して、IsCheckedの値に応じて表示するチェックマークの変更やBorderのBackground、BorderThicknessを変更します。
BorderThicknessについてはチェック時に0以上にして外枠と内側両方に色を設定した場合、色が綺麗に表示されないことがあったためこのようにしています。
今回はチェック状態のTriggerだけではなく、「チェックかつ、マウスオーバー」「未チェックかつ、マウスオーバー」の複合型のTriggerも設定します。
この場合は、MultiTriggerを利用することで実現可能です。
<ControlTemplate.Triggers> <!-- チェック時のスタイル --> <Trigger Property="IsChecked" Value="True"> <Setter TargetName="CheckMark" Property="Visibility" Value="Visible" /> <Setter TargetName="CheckBoxBorder" Property="Background" Value="{StaticResource CheckedBackColor}" /> <Setter TargetName="CheckBoxBorder" Property="BorderThickness" Value="{StaticResource CheckBorderThickness}" /> </Trigger> <!-- 不定時のスタイル --> <Trigger Property="IsChecked" Value="{x:Null}"> <Setter TargetName="IndeterminateMark" Property="Visibility" Value="Visible" /> </Trigger> <!-- 未チェック状態でマウスオーバー時のスタイル --> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsMouseOver" Value="True" /> <Condition Property="IsChecked" Value="False" /> </MultiTrigger.Conditions> <Setter TargetName="CheckMark" Property="Visibility" Value="Visible" /> <Setter TargetName="CheckMark" Property="Stroke" Value="{StaticResource CheckedBackColor}" /> <Setter TargetName="CheckMark" Property="Opacity" Value="0.2" /> </MultiTrigger> <!-- チェック状態でマウスオーバー時のスタイル --> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsMouseOver" Value="True" /> <Condition Property="IsChecked" Value="True" /> </MultiTrigger.Conditions> <Setter TargetName="CheckBoxBorder" Property="Opacity" Value="0.8" /> </MultiTrigger> </ControlTemplate.Triggers>
スタイルを適用する
それぞれの状態を確認できるように3つのチェックボックスを追加して、それぞれにスタイルを適用させています。間のLabelはスペース調整のためのもので深い意味はありません。
<StackPanel> <!-- スタイルの適用例 --> <CheckBox Content="未チェック状態" IsChecked="False" Style="{StaticResource MyCheckBox}" /> <Label Height="10" /> <CheckBox Content="チェック状態" IsChecked="True" Style="{StaticResource MyCheckBox}" /> <Label Height="10" /> <CheckBox Content="不定状態" IsChecked="{x:Null}" Style="{StaticResource MyCheckBox}" /> </StackPanel>
丸いスタイル2
イメージ
作成するスタイルは以下の通りです。上の例とは色のパターンを変更しています。
ソースコード
上の例から、以下の部分のみ変更することで対応可能です。ここでは上の例と異なりチェック状態のCheckBorderThicknessを2.0に設定してます。
<Window.Resources> <!-- チェックボックスのサイズや見た目関連 --> <Thickness x:Key="CheckBorderThickness">2.0</Thickness> <Thickness x:Key="UnCheckBorderThickness">2.0</Thickness> <CornerRadius x:Key="CheckBoxCornerRadius">20.0</CornerRadius> <!-- チェックボックスの色 --> <SolidColorBrush x:Key="CheckedBorderColor">#00b894</SolidColorBrush> <SolidColorBrush x:Key="CheckedBackColor">#ffffff</SolidColorBrush> <SolidColorBrush x:Key="UnCheckedBorderColor">#00b894</SolidColorBrush> <SolidColorBrush x:Key="UnCheckedBackColor">#ffffff</SolidColorBrush> <SolidColorBrush x:Key="CheckMarkColor">#00b894</SolidColorBrush> <SolidColorBrush x:Key="IndeterminateMarkColor">#d63031</SolidColorBrush>
なお、チェックマークの色、チェックボックスの色の変更に伴い、マウスオーバー時のスタイルも少し変更しています。
<ControlTemplate.Triggers> ・・・省略・・・ <!-- 未チェック状態でマウスオーバー時のスタイル --> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsMouseOver" Value="True" /> <Condition Property="IsChecked" Value="False" /> </MultiTrigger.Conditions> <Setter TargetName="CheckMark" Property="Visibility" Value="Visible" /> <Setter TargetName="CheckMark" Property="Stroke" Value="{StaticResource CheckMarkColor}" /> ←ここ <Setter TargetName="CheckMark" Property="Opacity" Value="0.2" /> </MultiTrigger> <!-- チェック状態でマウスオーバー時のスタイル --> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsMouseOver" Value="True" /> <Condition Property="IsChecked" Value="True" /> </MultiTrigger.Conditions> <Setter TargetName="CheckMark" Property="Opacity" Value="0.6" /> ←ここ </MultiTrigger> </ControlTemplate.Triggers>
角丸スタイル1
イメージ
作成するスタイルは以下の通りです。角丸な外観にしていますが他は最初の例と変わりません。CheckBoxCornerRadiusを調整するだけで対応可能です。
ソースコード
上の例と同様に以下の部分のみ変更することで対応可能です。
<Window.Resources> <!-- チェックボックスのサイズや見た目関連 --> <Thickness x:Key="CheckBorderThickness">0.0</Thickness> <Thickness x:Key="UnCheckBorderThickness">2.0</Thickness> <CornerRadius x:Key="CheckBoxCornerRadius">4.0</CornerRadius> <!-- チェックボックスの色 --> <SolidColorBrush x:Key="CheckedBorderColor">#0984e3</SolidColorBrush> <SolidColorBrush x:Key="CheckedBackColor">#0984e3</SolidColorBrush> <SolidColorBrush x:Key="UnCheckedBorderColor">#0984e3</SolidColorBrush> <SolidColorBrush x:Key="UnCheckedBackColor">#ffffff</SolidColorBrush> <SolidColorBrush x:Key="CheckMarkColor">White</SolidColorBrush> <SolidColorBrush x:Key="IndeterminateMarkColor">#d63031</SolidColorBrush>
角丸スタイル2
イメージ
作成するスタイルは以下の通りです。角丸な外観にしつつ2つ目の例と同じような色のパターンにしています。
ソースコード
上の例と同様に以下の部分のみ変更することで対応可能です。
<Window.Resources> <!-- チェックボックスのサイズや見た目関連 --> <Thickness x:Key="CheckBorderThickness">2.0</Thickness> <Thickness x:Key="UnCheckBorderThickness">2.0</Thickness> <CornerRadius x:Key="CheckBoxCornerRadius">4.0</CornerRadius> <!-- チェックボックスの色 --> <SolidColorBrush x:Key="CheckedBorderColor">#00b894</SolidColorBrush> <SolidColorBrush x:Key="CheckedBackColor">#ffffff</SolidColorBrush> <SolidColorBrush x:Key="UnCheckedBorderColor">#00b894</SolidColorBrush> <SolidColorBrush x:Key="UnCheckedBackColor">#ffffff</SolidColorBrush> <SolidColorBrush x:Key="CheckMarkColor">#00b894</SolidColorBrush> <SolidColorBrush x:Key="IndeterminateMarkColor">#d63031</SolidColorBrush>