[WPF/xaml]BasedOnを使って元のstyleを受け継ぐ

# やりたいこと
複数の似たstyleを作るとなったときに、共通する部分だけ1つのstyleにまとめたい。

# やり方
`BasedOn`を使う。

# 実験コード
下記のようなコードを書いて実験をした。
※Prismを使用しているので、画面はUserControlで作成。

```UserControl1.xaml
<UserControl x:Class="PrismSample.Views.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:PrismSample.Views"
             xmlns:prism="http://prismlibrary.com/"
             prism:ViewModelLocator.AutoWireViewModel="True"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UserControl.Resources>
        
        <!-- スタイル①：元になるスタイル -->
        <Style x:Key="MyButtonStyle" TargetType="Button">
            <Setter Property="Background" Value="Green"/>
            <Setter Property="Foreground" Value="Yellow"/>
            <Setter Property="BorderBrush" Value="Purple"/>
            <Setter Property="BorderThickness" Value="3"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Grid>
                            <Ellipse Stroke="{TemplateBinding BorderBrush}" Fill="{TemplateBinding Background}" 
                                     StrokeThickness="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderThickness.Top}"/>
                            <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <!-- スタイル②：元のスタイルをベースに変更を加えるスタイル -->
        <Style x:Key="MyButtonStyleEx" TargetType="Button" BasedOn="{StaticResource MyButtonStyle}">
            <Setter Property="BorderBrush" Value="Red"/>
            <Setter Property="BorderThickness" Value="20"/>
        </Style>
    </UserControl.Resources>

    <!-- 画面表示メイン -->
    <Grid Background="Beige">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="360"/>
        </Grid.RowDefinitions>

        <TextBlock Grid.Row="0" Text="画面" FontSize="60"/>
        <Button Grid.Row="1" Content="ボタン" Command="{Binding ButtonCommand}" Style="{DynamicResource MyButtonStyleEx}"/>
    </Grid>
</UserControl>
```

# 実験内容
二つのstyleを定義し実験。それぞれ下記のようにしている。

`スタイル①：元になるスタイル`
ボタン淵色　：紫
ボタン淵太さ：3pixel
ボタン背景　：緑
ボタン文字　：黄色
→このstyle単体で表示させると下記のようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/d59b4066-a84d-f9cd-4bd6-5c8dcaa91e11.png)

`スタイル②：元のスタイルをベースに変更を加えるスタイル`
ボタン淵色　：赤
ボタン淵太さ：20
ボタン背景　：指定なし
ボタン文字　：指定なし
→このstyleで表示させると下記のようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/bcdea15b-b3f7-d692-c76e-e9e66d88bb73.png)



# 動作結果
BasedOnを使って元のstyleを受け継ぐと、**受け継いだstyle側で指定したプロパティのみ上書き**され、そのほかのプロパティは元のstyleのままになる。

# 備考
`スタイル①：元になるスタイル`のほうで、`Template`を指定していないと、WPF標準のButtonのstyleを受け継ぐことになる。その場合、マウスOverしたときとか無効になった時の色の変化も受け継がれる。(=Templateを指定すると、まったく何も受け継がなくなり、1から作成になるイメージ)

試しに、`スタイル①：元になるスタイル`の`<Setter Property="Template">`のTemplate指定部分を丸ごと消すと、下記のようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/d69b65d4-a357-c54a-49bd-1c92a21127e1.png)

Templateで指定していた`Ellipse`などがなくなり、元のボタンのBorderTHicknessやBorderBrush、Backgroundが指定される形となる。
(マウスオーバー等させると、元のstyle通り、色も変わる)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/3eb614d9-5297-c30d-42dc-117faeab5bc7.png)

# 参照
Button Class
https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.controls.button?view=netframework-4.8