WPFのスタイルの継承について

WPFでアプリを作る際にスタイルの継承をしてみたかったので調べてみた。

「BasedOn」を指定することでスタイルの継承を行うことができる。
そのため、「基本スタイルの定義」->(継承)「コントロール共通のスタイルの定義」->(継承)「プロジェクトごとのスタイルの定義」とすることで、業務用アプリなどの同じ意味を持つコントロールの定義を一括で定義することができる。
業務用アプリだと「得意先CD」「得意先名」など同じ意味を持つテキストボックスコントロールが各画面にばらまかれるため、MaxLengthや色などを変更するときに作り方次第では画面ごとに修正が必要だが、共通スタイルを定義しておくことでResourceを修正するだけで全画面が直る。

ResourceDictionary.MergedDictionariesで継承元の定義しておいたXAMLを読み込んでいる。
最後にApp.xamlでも同じように定義を読み込む

サンプル)
[BasicResource.xaml]
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:SystemTemplate.resource"
                    >
    
    <!-- Active状態の背景色 -->
    <SolidColorBrush x:Key="ActiveBackColor" Color="#FFF4FDBE"></SolidColorBrush>

    <!-- テーマカラー -->
    <SolidColorBrush x:Key="WindowColor" Color="#FFF4F9FF"></SolidColorBrush>

    <!--#region 継承元のスタイル-->
    <!-- 継承元のフォームベースのスタイル -->
    <Style x:Key="WindowStyleBase" TargetType="Window">
        <!--<Setter Property="Icon" Value="images/icon.ico"></Setter>-->
        <Setter Property="FontFamily" Value="MS Gothic" />
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="Background" Value="{StaticResource WindowColor}"></Setter>
        <Setter Property="WindowStyle" Value="SingleBorderWindow"></Setter>
        <Setter Property="TextOptions.TextFormattingMode" Value="Ideal"></Setter>
        <Setter Property="TextOptions.TextRenderingMode" Value="Auto"></Setter>
    </Style>


    <Style TargetType="UserControl" x:Key="UserControlBaseStyle">
        <Setter Property="FontSize" Value="11.5"/>
        <Setter Property="FontFamily" Value="MS Gothic"/>
    </Style>

    <Style x:Key="TextBlockStyleBase" TargetType="TextBlock">
        <Setter Property="FontFamily" Value="MS Gothic" />
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="TextAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
    </Style>

    <Style x:Key="TextBoxStyleBase" TargetType="TextBox">
        <Setter Property="FontFamily" Value="MS Gothic" />
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="TextAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Height" Value="25"/>

        <!-- フォーカス時に背景色を設定 -->
        <Style.Triggers>
            <Trigger Property="IsFocused" Value="True">
                <!--IsFocusedがTrueの場合、下の値を適用-->
                <Setter Property="Background" Value="{StaticResource ActiveBackColor}" />
            </Trigger>
            <Trigger Property="IsFocused" Value="False">
                <Setter Property="Background" Value="White" />
            </Trigger>
        </Style.Triggers>

    </Style>


    <Style x:Key="PasswordBoxStyleBase" TargetType="PasswordBox">
        <Setter Property="FontFamily" Value="MS Gothic" />
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Height" Value="25"/>

        <!-- フォーカス時に背景色を設定 -->
        <Style.Triggers>
            <Trigger Property="IsFocused" Value="True">
                <!--IsFocusedがTrueの場合、下の値を適用-->
                <Setter Property="Background" Value="{StaticResource ActiveBackColor}" />
            </Trigger>
            <Trigger Property="IsFocused" Value="False">
                <Setter Property="Background" Value="White" />
            </Trigger>
        </Style.Triggers>

    </Style>

    <Style x:Key="LabelStyleBaseNoHeight" TargetType="Label">
        <Setter Property="FontFamily" Value="MS Gothic" />
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="BorderBrush" Value="Black"/>
        <Setter Property="BorderThickness" Value="1"/>
    </Style>

    <Style x:Key="LabelStyleBase" TargetType="Label" BasedOn="{StaticResource LabelStyleBaseNoHeight}">
        <Setter Property="Height" Value="25"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
    </Style>

    <Style x:Key="DataGridStyleBase" TargetType="DataGrid">
        <Setter Property="FontFamily" Value="MS Gothic" />
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="HorizontalGridLinesBrush" Value="Silver"/>
        <Setter Property="VerticalGridLinesBrush" Value="Silver"/>
        <Setter Property="AlternatingRowBackground" Value="#FFD8FFFD"/>
        <!--<Setter Property="Height" Value="25"/>-->
    </Style>

    <!-- 影付きのボタンにするためのエフェクト -->
    <DropShadowEffect x:Key="ButtonEffect" BlurRadius="0" RenderingBias="Quality" ShadowDepth="2"/>
    <Style x:Key="ButtonStyleBase" TargetType="Button">
        <Setter Property="FontFamily" Value="MS Gothic" />
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="BorderBrush" Value="Black"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Height" Value="25"/>
        <Setter Property="Effect" Value="{StaticResource ButtonEffect}"/>

        <Style.Triggers>

            <!-- フォーカス時の背景色 -->
            <Trigger Property="IsFocused" Value="True">
                <Setter Property="Background" Value="{StaticResource ActiveBackColor}"></Setter>
            </Trigger>
        </Style.Triggers>

    </Style>

    <!-- TextBlock縦書 -->
    <Style x:Key="TextBlockVerticalWriting"  TargetType="{x:Type TextBlock}">
        <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
        <Setter Property="Margin" Value="0.0,0.0"/>
        <Setter Property="Width" Value="Auto"/>
        <Setter Property="TextOptions.TextFormattingMode" Value="Display"/>
        <Setter Property="RenderTransform">
            <Setter.Value>
                <TransformGroup>
                    <ScaleTransform ScaleX="1" ScaleY="1"/>
                    <SkewTransform AngleX="0" AngleY="0"/>
                    <RotateTransform Angle="0"/>
                    <TranslateTransform X="0" Y="0"/>
                </TransformGroup>
            </Setter.Value>
        </Setter>
        <Setter Property="LayoutTransform">
            <Setter.Value>
                <TransformGroup>
                    <ScaleTransform ScaleX="1" ScaleY="1"/>
                    <SkewTransform AngleX="0" AngleY="0"/>
                    <RotateTransform Angle="90"/>
                    <TranslateTransform X="0" Y="0"/>
                </TransformGroup>
            </Setter.Value>
        </Setter>
    </Style>

    <!--#endregion-->
</ResourceDictionary>

[ControlResource] コントロールごとの共通スタイルを定義
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:SystemTemplate.resource"
                    >

    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="BaseResorce.xaml"/>
    </ResourceDictionary.MergedDictionaries>

    <!--#region 継承後のスタイル-->

    <Style x:Key="NormalLabel" TargetType="Label" BasedOn="{StaticResource LabelStyleBase}">
        <Setter Property="Background" Value="#FFCEE4FF" />
    </Style>
    <Style x:Key="NormalLabelNoHeight" TargetType="Label" BasedOn="{StaticResource LabelStyleBaseNoHeight}">
        <Setter Property="Background" Value="#FFCEE4FF" />
    </Style>

    <Style TargetType="UserControl" x:Key="CsDate" BasedOn="{StaticResource UserControlBaseStyle}">
    </Style>

    <Style x:Key="TitleLabel" TargetType="Label" BasedOn="{StaticResource LabelStyleBase}">
        <Setter Property="Background" Value="#FF7BB7FF" />
    </Style>

    <Style x:Key="RequiredLabel" TargetType="Label" BasedOn="{StaticResource LabelStyleBase}">
        <!--<Setter Property="Background" Value="#FFFF997B" />-->
        <Setter Property="Background" Value="#FF7BB7FF" />
    </Style>

    <Style x:Key="SimpleLabel" TargetType="Label" BasedOn="{StaticResource LabelStyleBase}">
        <Setter Property="BorderThickness" Value="0"/>
    </Style>

    <Style x:Key="NormalTextBlock" TargetType="TextBlock" BasedOn="{StaticResource TextBlockStyleBase}">
    </Style>

    <Style x:Key="NormalPasswordBox" TargetType="PasswordBox" BasedOn="{StaticResource PasswordBoxStyleBase}">
    </Style>


    <!--#region DataGrid関連 -->

    <!-- ヘッダセルに対する書式設定
                 ・ヘッダ部は水平中央寄せ
            -->
    <Style x:Key="DataGridHeaderCellCenter" TargetType="DataGridColumnHeader">
        <Setter Property="HorizontalContentAlignment"  Value="Center"/>
    </Style>

    <!-- 各セルに対する書式設定
                 ・セルの垂直中央寄せ
            -->
    <Style x:Key="DataGridCellCenter" TargetType="DataGridCell" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGridCell}">
                    <Grid Background="{TemplateBinding Background}">
                        <ContentPresenter VerticalAlignment="Center" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

    </Style>

    <Style x:Key="NormalDataGrid" TargetType="DataGrid" BasedOn="{StaticResource DataGridStyleBase}">
        <Setter Property="RowHeight" Value="20"/>
        <Setter Property="ColumnHeaderStyle" Value="{StaticResource DataGridHeaderCellCenter}" />
        <Setter Property="CellStyle" Value="{StaticResource DataGridCellCenter}" />
    </Style>


    <Style x:Key="DataGridAutoRowHeight" TargetType="DataGrid" BasedOn="{StaticResource DataGridStyleBase}">
        <Setter Property="ColumnHeaderStyle" Value="{StaticResource DataGridHeaderCellCenter}" />
        <Setter Property="CellStyle" Value="{StaticResource DataGridCellCenter}" />
    </Style>

    <Style x:Key="DataGridCellElementStyleCenter" TargetType="{x:Type TextBlock}">
        <Setter Property="TextAlignment" Value="Center" />
    </Style>

    <Style x:Key="DataGridCellElementStyleLeft" TargetType="{x:Type TextBlock}">
        <Setter Property="TextAlignment" Value="Left" />
    </Style>

    <Style x:Key="DataGridCellElementStyleRight" TargetType="{x:Type TextBlock}">
        <Setter Property="TextAlignment" Value="Right" />
        <Setter Property="Margin" Value="0,0,5,0" />
    </Style>

    <!--#endregion DataGrid関連 -->

    <Style x:Key="SystemTitleTextBlock" TargetType="TextBlock" BasedOn="{StaticResource TextBlockStyleBase}">
        <Setter Property="FontFamily" Value="MS Gothic"/>
        <Setter Property="FontSize" Value="24"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
    </Style>


    <Style x:Key="TitleTextBlock" TargetType="TextBlock" BasedOn="{StaticResource TextBlockStyleBase}">
        <Setter Property="FontFamily" Value="MS Gothic"/>
        <Setter Property="FontSize" Value="13"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
    </Style>

    <Style x:Key="SupplementTextBlock" TargetType="TextBlock" BasedOn="{StaticResource TextBlockStyleBase}">
        <Setter Property="FontSize" Value="10"/>
        <Setter Property="Foreground" Value="#FF616161"/>
    </Style>

    <!--▽ 通常のテキストボックスのスタイル -->
    <Style x:Key="NormalTextBox" TargetType="TextBox" BasedOn="{StaticResource TextBoxStyleBase}">
    </Style>

    <!--▽ 読み取り専用のテキストボックスのスタイル -->
    <Style x:Key="ReadOnlyTextBox" TargetType="TextBox" BasedOn="{StaticResource TextBoxStyleBase}">
        <Setter Property="IsReadOnly" Value="True"/>
        <Setter Property="Background" Value="WhiteSmoke"/>
    </Style>

    <!--▽ 複数行のテキストボックスのスタイル -->
    <Style x:Key="MultiLineTextBox" TargetType="TextBox" BasedOn="{StaticResource TextBoxStyleBase}">
        <Setter Property="AcceptsReturn" Value="True"/>
        <Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="HorizontalScrollBarVisibility" Value="Auto"/>
        <Setter Property="VerticalAlignment" Value="Top"/>
        <Setter Property="VerticalContentAlignment" Value="Top"/>
        <Setter Property="TextWrapping" Value="Wrap"/>
        <Setter Property="Padding" Value="2"/>
    </Style>

    <Style x:Key="NormalButton" TargetType="Button" BasedOn="{StaticResource ButtonStyleBase}">
    </Style>

    <Style x:Key="MenuButton" TargetType="Button" BasedOn="{StaticResource ButtonStyleBase}">
        <Setter Property="HorizontalContentAlignment" Value="Left"/>
        <Setter Property="Margin" Value="10"/>
    </Style>
    
    <Style x:Key="WindowStyle" TargetType="Window" BasedOn="{StaticResource WindowStyleBase}">
    </Style>

    <Style x:Key="SignInWindowStyle" TargetType="Window" BasedOn="{StaticResource WindowStyleBase}">
        <!--<Setter Property="Background">
                    <Setter.Value>
                        <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                            <LinearGradientBrush.GradientStops>
                                <GradientStop Offset="0.0" Color="#FFB0FFB0"/>
                                
                <GradientStop Offset="1.0" Color="#FFD6D6D6"/>
                
                                <GradientStop Offset="1.0" Color="#FFB6DAA2"/>
                            </LinearGradientBrush.GradientStops>
                        </LinearGradientBrush>
                    </Setter.Value>
            </Setter>-->
    </Style>


    <Style x:Key="GridSplitterStyle" TargetType="GridSplitter">
        <Setter Property="Background" Value="LightGray"></Setter>
        <Setter Property="ShowsPreview" Value="True"></Setter>
        <Setter Property="IsTabStop" Value="False"></Setter>
    </Style>


</ResourceDictionary>

[ProjectResource] プロジェクト(案件)ごとのスタイルを定義
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:SystemTemplate.resource"
                    xmlns:convreter="clr-namespace:SystemTemplate.resource.converter"
                    
                    >
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="ControlResource.xaml"/>
    </ResourceDictionary.MergedDictionaries>

    <convreter:StringToNumberConverter x:Key="stringToNumberConverter" />

    <!--#region Window -->
    <Style x:Key="LoginWindowStyle" TargetType="Window" BasedOn="{StaticResource WindowStyle}">
    </Style>

    <Style x:Key="MenuWindowStyle" TargetType="Window" BasedOn="{StaticResource WindowStyle}">
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="Height" Value="740"/>
        <Setter Property="Width" Value="980"/>
    </Style>

    <Style x:Key="ShnWindowStyle" TargetType="Window" BasedOn="{StaticResource WindowStyle}">
        <Setter Property="Height" Value="740"/>
        <Setter Property="Width" Value="980"/>
    </Style>

    <!--#region ユーザーマスタ -->
    <Style x:Key="txtUserCDStyle" TargetType="TextBox" BasedOn="{StaticResource  NormalTextBox}">
        <Setter Property="MaxLength" Value="4"/>
        
        <!--数値入力のみとする-->
        <Setter Property="InputMethod.IsInputMethodEnabled" Value="False"/>
    </Style>

    <Style x:Key="txtPassWord" TargetType="TextBox" BasedOn="{StaticResource  NormalTextBox}">
        <Setter Property="MaxLength" Value="10"/>
    </Style>
     <!--#endregion-->

    <Style x:Key="txtTnkStyle" TargetType="TextBox" BasedOn="{StaticResource  NormalTextBox}">
        <Setter Property="MaxLength" Value="9"/>

        <Setter Property="InputMethod.IsInputMethodEnabled" Value="False"/>
        
        <!--カンマ区切りで小数点以下なし表示-->
        <Setter Property="Text" Value="{Binding Path=., Converter={StaticResource stringToNumberConverter}}" />

    </Style>

</ResourceDictionary>

[App.xaml]
<Application x:Class="SystemTemplate.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:SystemTemplate"
             StartupUri="win00_0000_Login.xaml">
    <Application.Resources>
        <ResourceDictionary>

            
            <!-- Static Resourceが設定されていないコントロールを判別するためのスタイル。個別でStaticResouceを設定していればそちらが上書きされる -->
            <Style TargetType="TextBox">
                <Setter Property="Background" Value="Red"/>
            </Style>

            <!--#region プロジェクトごとのコントロールを定義したリソース -->
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="resource\ProjectResource.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <!--#endregion-->
            
        </ResourceDictionary>


    </Application.Resources>
</Application>

PowerShellでEdgeを自動化(インストール不要。参考:郵便追跡サービス自動操作)

1.経緯について  RPAのソフトをインストールできないので、これまでVBSでCreateObjectでブラウザの自動操作をすることがたまにあった。 ※いざというときの手札として持っているだけで安心感が段違い  見た目上IEがインストールされていなくても、CreateObject...