次の方法で共有


コントロールのスタイルを作成する方法

Windows Presentation Foundation (WPF) を使用すると、既存のコントロールの外観を独自の再利用可能なスタイルでカスタマイズできます。 スタイルは、アプリ、ウィンドウ、ページにグローバルに適用することも、コントロールに直接適用することもできます。

スタイルの作成

Styleは、プロパティ値のセットを 1 つ以上の要素に適用する便利な方法と考えることができます。 FrameworkElementFrameworkContentElementなど、WindowまたはButtonから派生する任意の要素でスタイルを使用できます。

スタイルを宣言する最も一般的な方法は、XAML ファイルの Resources セクションのリソースです。 スタイルはリソースであるため、すべてのリソースに適用されるのと同じスコープ規則に従います。 簡単に言えば、スタイルを宣言する場所は、スタイルを適用できる場所に影響します。 たとえば、アプリ定義 XAML ファイルのルート要素でスタイルを宣言した場合、スタイルはアプリ内の任意の場所で使用できます。

<Application x:Class="IntroToStylingAndTemplating.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:IntroToStylingAndTemplating"
             StartupUri="WindowExplicitStyle.xaml">
    <Application.Resources>
        <ResourceDictionary>
            
            <Style x:Key="Header1" TargetType="TextBlock">
                <Setter Property="FontSize" Value="15" />
                <Setter Property="FontWeight" Value="ExtraBold" />
            </Style>
            
        </ResourceDictionary>
    </Application.Resources>
</Application>

アプリのいずれかの XAML ファイルでスタイルを宣言した場合、その XAML ファイルでのみスタイルを使用できます。 リソースのスコープ規則の詳細については、「 XAML リソースの概要」を参照してください。

<Window x:Class="IntroToStylingAndTemplating.WindowSingleResource"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:IntroToStylingAndTemplating"
        mc:Ignorable="d"
        Title="WindowSingleResource" Height="450" Width="800">
    <Window.Resources>
        
        <Style x:Key="Header1" TargetType="TextBlock">
            <Setter Property="FontSize" Value="15" />
            <Setter Property="FontWeight" Value="ExtraBold" />
        </Style>
        
    </Window.Resources>
    <Grid />
</Window>

スタイルは、スタイル <Setter> 適用される要素にプロパティを設定する子要素で構成されます。 上記の例では、スタイルが TextBlock 属性を介してTargetType型に適用するように設定されていることに注意してください。 スタイルによって FontSize15 に設定され、 FontWeightExtraBoldに設定されます。 スタイルが変更されるプロパティごとに <Setter> を追加します。

スタイルを暗黙的に適用する

Styleは、複数の要素にプロパティ値のセットを適用する便利な方法です。 たとえば、次の TextBlock 要素と、ウィンドウ内の既定の外観を考えてみましょう。

<StackPanel>
    <TextBlock>My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

前のスタイル設定サンプルのスクリーンショット

FontSizeFontFamilyなどのプロパティを各TextBlock要素に直接設定することで、既定の外観を変更できます。 ただし、TextBlock要素でいくつかのプロパティを共有する場合は、次に示すように、XAML ファイルの Style セクションにResourcesを作成できます。

<Window.Resources>
    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

スタイルの TargetTypeTextBlock 型に設定し、 x:Key 属性を省略すると、スタイルをスコープとするすべての TextBlock 要素 (通常は XAML ファイル自体) にスタイルが適用されます。

次に、 TextBlock 要素が次のように表示されます。

サンプルのスタイリング スクリーンショット基本スタイル

スタイルを明示的に適用する

スタイルに値を持つ x:Key 属性を追加すると、スタイルは TargetTypeのすべての要素に暗黙的に適用されなくなります。 スタイルを明示的に参照する要素にのみ、スタイルが適用されます。

前のセクションのスタイルを次に示しますが、 x:Key 属性で宣言されています。

<Window.Resources>
    <Style x:Key="TitleText" TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
</Window.Resources>

スタイルを適用するには、次に示すように、Styleを使用して、要素のx:Key プロパティを値に設定します。

<StackPanel>
    <TextBlock Style="{StaticResource TitleText}">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

最初の TextBlock 要素にスタイルが適用されているのに対し、2 番目の TextBlock 要素は変更されていないことに注意してください。 前のセクションの暗黙的なスタイルが、 x:Key 属性を宣言したスタイルに変更されました。つまり、スタイルの影響を受ける唯一の要素は、スタイルを直接参照する要素です。

テキスト ブロックのスタイル設定のサンプル スクリーンショット

明示的または暗黙的にスタイルを適用すると、スタイルはシールされ、変更できなくなります。 適用されているスタイルを変更する場合は、既存のスタイルを置き換える新しいスタイルを作成します。 詳細については、 IsSealed プロパティを参照してください。

カスタム ロジックに基づいて適用するスタイルを選択するオブジェクトを作成できます。 例については、 StyleSelector クラスに提供されている例を参照してください。

プログラムでスタイルを適用する

名前付きスタイルをプログラムで要素に割り当てるには、リソース コレクションからスタイルを取得し、要素の Style プロパティに割り当てます。 リソース コレクション内の項目の種類は Objectです。 したがって、取得したスタイルをSystem.Windows.Style プロパティに割り当てる前に、Styleにキャストする必要があります。 たとえば、次のコードは、TextBlockという名前のtextblock1のスタイルを定義済みのスタイル TitleTextに設定します。

textblock1.Style = (Style)Resources["TitleText"];
textblock1.Style = CType(Resources("TitleText"), Windows.Style)

スタイルを拡張する

2 つの TextBlock 要素で、 FontFamily や中央揃えの HorizontalAlignmentなど、いくつかのプロパティ値を共有したい場合があります。 ただし、[ マイピクチャ] というテキストには追加のプロパティも含める必要があります。 これを行うには、次に示すように、最初のスタイルに基づく新しいスタイルを作成します。

<Window.Resources>
    <!-- .... other resources .... -->

    <!--A Style that affects all TextBlocks-->
    <Style TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="FontFamily" Value="Comic Sans MS"/>
        <Setter Property="FontSize" Value="14"/>
    </Style>
    
    <!--A Style that extends the previous TextBlock Style with an x:Key of TitleText-->
    <Style BasedOn="{StaticResource {x:Type TextBlock}}"
           TargetType="TextBlock"
           x:Key="TitleText">
        <Setter Property="FontSize" Value="26"/>
        <Setter Property="Foreground">
            <Setter.Value>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <LinearGradientBrush.GradientStops>
                        <GradientStop Offset="0.0" Color="#90DDDD" />
                        <GradientStop Offset="1.0" Color="#5BFFFF" />
                    </LinearGradientBrush.GradientStops>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

次に、スタイルを TextBlockに適用します。

<StackPanel>
    <TextBlock Style="{StaticResource TitleText}" Name="textblock1">My Pictures</TextBlock>
    <TextBlock>Check out my new pictures!</TextBlock>
</StackPanel>

このTextBlockスタイルは中央揃えになり、Comic Sans MSのサイズを持つ26フォントを使用し、前景色は例に示すLinearGradientBrushに設定されています。 基本スタイルの FontSize 値がオーバーライドされていることに注意してください。 Setter内に同じプロパティを指すStyleが複数ある場合は、最後に宣言されたSetterが優先されます。

次に、 TextBlock 要素の外観を示します。

スタイル付きテキストブロック

このTitleText スタイルは、TextBlockで参照されるBasedOn="{StaticResource {x:Type TextBlock}}"型用に作成されたスタイルを拡張します。 スタイルのx:Keyを使用して、x:Keyを持つスタイルを拡張することもできます。 たとえば、 Header1 という名前のスタイルがあり、そのスタイルを拡張する場合は、 BasedOn="{StaticResource Header1}"を使用します。

TargetType プロパティと x:Key 属性のリレーションシップ

前に示したように、TargetTypeスタイルを割り当てずに TextBlock プロパティを x:Key に設定すると、スタイルはすべてのTextBlock要素に適用されます。 この場合、 x:Key は暗黙的に {x:Type TextBlock}に設定されます。 つまり、 x:Key 値を {x:Type TextBlock}以外に明示的に設定した場合、 Style はすべての TextBlock 要素に自動的に適用されません。 代わりに、スタイルを ( x:Key 値を使用して) TextBlock 要素に明示的に適用する必要があります。 スタイルが resources セクションにあり、スタイルに TargetType プロパティを設定していない場合は、 x:Key 属性を設定する必要があります。

x:Keyの既定値を指定するだけでなく、TargetType プロパティはセッター プロパティが適用される型を指定します。 TargetTypeを指定しない場合は、構文Setterを使用して、Property="ClassName.Property" オブジェクトのプロパティをクラス名で修飾する必要があります。 たとえば、 Property="FontSize"を設定する代わりに、 Property"TextBlock.FontSize" または "Control.FontSize"に設定する必要があります。

また、多くの WPF コントロールは、他の WPF コントロールの組み合わせで構成されていることにも注意してください。 型のすべてのコントロールに適用されるスタイルを作成すると、予期しない結果が得られる可能性があります。 たとえば、TextBlockWindow型を対象とするスタイルを作成した場合、TextBlockTextBlockなどの別のコントロールの一部である場合でも、そのスタイルはウィンドウ内のすべてのListBox コントロールに適用されます。

こちらも参照ください