3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at

やりたいこと

複数の似た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

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?