Help us understand the problem. What is going on with this article?

[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

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

image.png

動作結果

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

備考

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

試しに、スタイル①:元になるスタイル<Setter Property="Template">のTemplate指定部分を丸ごと消すと、下記のようになる。
image.png

Templateで指定していたEllipseなどがなくなり、元のボタンのBorderTHicknessやBorderBrush、Backgroundが指定される形となる。
(マウスオーバー等させると、元のstyle通り、色も変わる)
image.png

参照

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした