スタイルとテンプレート (WPF .NET)Styles and templates (WPF .NET)

Windows Presentation Foundation (WPF) のスタイルとテンプレートは、開発者と設計者が視覚的に説得力のある効果と、製品の一貫した外観を作成するために使用できる一連の機能を指します。Windows Presentation Foundation (WPF) styling and templating refer to a suite of features that let developers and designers create visually compelling effects and a consistent appearance for their product. アプリの外観をカスタマイズするときは、アプリ内およびアプリ間での外観の保守と共有を可能にする、強力なスタイルとテンプレートのモデルが必要です。When customizing the appearance of an app, you want a strong styling and templating model that enables maintenance and sharing of appearance within and among apps. WPF はそのモデルを提供します。WPF provides that model.

WPF スタイル モデルのもう 1 つの機能は、表示とロジックの分離です。Another feature of the WPF styling model is the separation of presentation and logic. 設計者は、開発者が C# や Visual Basic を使用してプログラミング ロジックの作業を行っているのと同時に、XAML のみを使用してアプリの外観に関する作業を行うことができます。Designers can work on the appearance of an app by using only XAML at the same time that developers work on the programming logic by using C# or Visual Basic.

この概要では、アプリのスタイルとテンプレートの側面に焦点を当てており、データ バインディングの概念については説明しません。This overview focuses on the styling and templating aspects of the app and doesn't discuss any data-binding concepts. データ バインディングの詳細については、「データ バインディングの概要」を参照してください。For information about data binding, see Data Binding Overview.

スタイルとテンプレートの再利用を可能にするものである、リソースについて理解しておくことも重要です。It's important to understand resources, which are what enable styles and templates to be reused. リソースの詳細については、XAML リソースの概要に関するページを参照してください。For more information about resources, see Overview of XAML resources.

重要

.NET 5 (および .NET Core) 用のデスクトップ ガイド ドキュメントは作成中です。The Desktop Guide documentation for .NET 5 (and .NET Core) is under construction.

サンプルSample

この概要で提供されているサンプル コードは、次の図に示す単純な写真閲覧アプリケーションに基づいています。The sample code provided in this overview is based on a simple photo browsing application shown in the following illustration.

スタイル設定された ListView

この単純な写真のサンプルは、スタイルとテンプレートを使用して、視覚的に説得力のあるユーザー エクスペリエンスを作成します。This simple photo sample uses styling and templating to create a visually compelling user experience. このサンプルには、2 つの TextBlock 要素と、画像一覧にバインドされた ListBox コントロールがあります。The sample has two TextBlock elements and a ListBox control that is bound to a list of images.

完全なサンプルについては、「Introduction to Styling and Templating Sample」を参照してください。For the complete sample, see Introduction to Styling and Templating Sample.

スタイルStyles

Style は、一連のプロパティ値を複数の要素に適用する便利な方法と考えることができます。You can think of a Style as a convenient way to apply a set of property values to multiple elements. FrameworkElement または FrameworkContentElement から派生する任意の要素 (WindowButton など) にスタイルを使用できます。You can use a style on any element that derives from FrameworkElement or FrameworkContentElement such as a Window or a Button.

スタイルを宣言する最も一般的な方法は、XAML ファイルの Resources セクションでリソースとして行うものです。The most common way to declare a style is as a resource in the Resources section in a XAML file. スタイルはリソースであるため、すべてのリソースに適用されるものと同じスコープ規則に従います。Because styles are resources, they obey the same scoping rules that apply to all resources. つまり、スタイルを宣言する場所は、スタイルを適用できる場所に影響するということです。Put simply, where you declare a style affects where the style can be applied. たとえば、アプリ定義 XAML ファイルのルート要素でスタイルを宣言すると、そのスタイルは、アプリ内のどこでも使用できます。For example, if you declare the style in the root element of your app definition XAML file, the style can be used anywhere in your app.

たとえば、次の XAML コードは、TextBlock の 2 つのスタイルを宣言しています。1 つは、すべての TextBlock 要素に自動的に適用され、もう 1 つは明示的に参照する必要があります。For example, the following XAML code declares two styles for a TextBlock, one automatically applied to all TextBlock elements, and another that must be explicitly referenced.

<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>

上記で宣言されたスタイルの使用例を次に示します。Here is an example of the styles declared above being used.

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

スタイル設定された TextBlock

詳細については、コントロールのスタイルの作成に関するページを参照してください。For more information, see Create a style for a control.

ControlTemplateControlTemplates

WPF では、コントロールの ControlTemplate によって、コントロールの外観が定義されます。In WPF, the ControlTemplate of a control defines the appearance of the control. コントロールの構造と外観を変更するには、新しい ControlTemplate を定義し、それをコントロールに割り当てます。You can change the structure and appearance of a control by defining a new ControlTemplate and assigning it to a control. 多くの場合、テンプレートによって、独自のカスタム コントロールを作成する必要がない程度に十分な柔軟性を得られます。In many cases, templates give you enough flexibility so that you do not have to write your own custom controls.

各コントロールでは、Control.Template プロパティに既定のテンプレートが割り当てられています。Each control has a default template assigned to the Control.Template property. このテンプレートは、コントロールの視覚表現とコントロールの機能を結びつけます。The template connects the visual presentation of the control with the control's capabilities. テンプレートは XAML で定義するため、コードを記述することなく、コントロールの外観を変更することができます。Because you define a template in XAML, you can change the control's appearance without writing any code. 各テンプレートは、Button などの特定のコントロール向けに設計されています。Each template is designed for a specific control, such as a Button.

一般に、テンプレートは、XAML ファイルの Resources セクションでリソースとして宣言します。Commonly you declare a template as a resource on the Resources section of a XAML file. すべてのリソースと同様に、スコープ規則が適用されます。As with all resources, scoping rules apply.

コントロール テンプレートは、スタイルよりもはるかに複雑です。Control templates are a lot more involved than a style. これは、スタイルが単にプロパティ変更を既存のコントロールに適用するのに対し、コントロール テンプレートはコントロール全体の外観を書き換えるからです。This is because the control template rewrites the visual appearance of the entire control, while a style simply applies property changes to the existing control. ただし、コントロールのテンプレートは、Control.Template プロパティを設定して適用されるため、スタイルを使用してテンプレートを定義または設定することができます。However, since the template of a control is applied by setting the Control.Template property, you can use a style to define or set a template.

通常、デザイナーでは、既存のテンプレートのコピーを作成して変更することが許可されます。Designers generally allow you to create a copy of an existing template and modify it. たとえば、Visual Studio WPF デザイナーで CheckBox コントロールを選択してから、右クリックし、 [テンプレートの編集] > [コピーの作成] を選択します。For example, in the Visual Studio WPF designer, select a CheckBox control, and then right-click and select Edit template > Create a copy. このコマンドは、"テンプレートを定義するスタイル" を生成します。This command generates a style that defines a template.

<Style x:Key="CheckBoxStyle1" TargetType="{x:Type CheckBox}">
    <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual1}"/>
    <Setter Property="Background" Value="{StaticResource OptionMark.Static.Background1}"/>
    <Setter Property="BorderBrush" Value="{StaticResource OptionMark.Static.Border1}"/>
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <Border x:Name="checkBoxBorder" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                        <Grid x:Name="markGrid">
                            <Path x:Name="optionMark" Data="F1 M 9.97498,1.22334L 4.6983,9.09834L 4.52164,9.09834L 0,5.19331L 1.27664,3.52165L 4.255,6.08833L 8.33331,1.52588e-005L 9.97498,1.22334 Z " Fill="{StaticResource OptionMark.Static.Glyph1}" Margin="1" Opacity="0" Stretch="None"/>
                            <Rectangle x:Name="indeterminateMark" Fill="{StaticResource OptionMark.Static.Glyph1}" Margin="2" Opacity="0"/>
                        </Grid>
                    </Border>
                    <ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="HasContent" Value="true">
                        <Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual1}"/>
                        <Setter Property="Padding" Value="4,-1,0,0"/>

... content removed to save space ...

テンプレートのコピーを編集することは、テンプレートの動作を理解するための優れた方法です。Editing a copy of a template is a great way to learn how templates work. 新しい空のテンプレートを作成する代わりに、コピーを編集して、視覚表示のいくつかの側面を変更する方が簡単です。Instead of creating a new blank template, it's easier to edit a copy and change a few aspects of the visual presentation.

詳細については、「コントロールのためのテンプレートを作成する」を参照してください。For an example, see Create a template for a control.

TemplateBindingTemplateBinding

前のセクションで定義されたテンプレート リソースで、TemplateBinding マークアップ拡張機能が使用されていることにお気付きかもしれません。You may have noticed that the template resource defined in the previous section uses the TemplateBinding Markup Extension. TemplateBinding は、テンプレート シナリオに合わせて最適化されたバインディングの形態であり、{Binding RelativeSource={RelativeSource TemplatedParent}} を使用して構築されたバインディングに似ています。A TemplateBinding is an optimized form of a binding for template scenarios, analogous to a binding constructed with {Binding RelativeSource={RelativeSource TemplatedParent}}. TemplateBinding は、テンプレートの一部をコントロールのプロパティにバインドするのに便利です。TemplateBinding is useful for binding parts of the template to properties of the control. たとえば、各コントロールには BorderThickness プロパティがあります。For example, each control has a BorderThickness property. TemplateBinding を使用して、テンプレート内のどの要素がこのコントロール設定の影響を受けるかを管理します。Use a TemplateBinding to manage which element in the template is affected by this control setting.

ContentControl と ItemsControlContentControl and ItemsControl

ContentPresenterContentControlControlTemplate で宣言されている場合、ContentPresenter は自動的に ContentTemplate および Content プロパティにバインドされます。If a ContentPresenter is declared in the ControlTemplate of a ContentControl, the ContentPresenter will automatically bind to the ContentTemplate and Content properties. 同様に、ItemsControlControlTemplate にある ItemsPresenter は、自動的に ItemTemplate および Items プロパティにバインドされます。Likewise, an ItemsPresenter that is in the ControlTemplate of an ItemsControl will automatically bind to the ItemTemplate and Items properties.

DataTemplateDataTemplates

このサンプル アプリには、写真のリストにバインドされている ListBox コントロールがあります。In this sample app, there is a ListBox control that is bound to a list of photos.

<ListBox ItemsSource="{Binding Source={StaticResource MyPhotos}}"
         Background="Silver" Width="600" Margin="10" SelectedIndex="0"/>

現在、この ListBox は次のようになっています。This ListBox currently looks like the following.

テンプレート適用前の ListBox

ほとんどのコントロールはいくつかの型のコンテンツを持ち、そのコンテンツは多くの場合バインディング先のデータから取得されます。Most controls have some type of content, and that content often comes from data that you are binding to. このサンプルでは、データは写真のリストです。In this sample, the data is the list of photos. WPF では、DataTemplate を使用してデータの視覚表現を定義します。In WPF, you use a DataTemplate to define the visual representation of data. 基本的には、DataTemplate に配置するものによって、レンダリングされたアプリでのデータの表示方法が決まります。Basically, what you put into a DataTemplate determines what the data looks like in the rendered app.

サンプル アプリでは、各カスタム Photo オブジェクトに、画像のファイル パスを指定する文字列型の Source プロパティがあります。In our sample app, each custom Photo object has a Source property of type string that specifies the file path of the image. 現在のところ、写真オブジェクトは、ファイルのパスとして表示されます。Currently, the photo objects appear as file paths.

public class Photo
{
    public Photo(string path)
    {
        Source = path;
    }

    public string Source { get; }

    public override string ToString() => Source;
}
Public Class Photo
    Sub New(ByVal path As String)
        Source = path
    End Sub

    Public ReadOnly Property Source As String

    Public Overrides Function ToString() As String
        Return Source
    End Function
End Class

写真を画像として表示するには、リソースとして DataTemplate を作成します。For the photos to appear as images, you create a DataTemplate as a resource.

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

    <!--DataTemplate to display Photos as images
    instead of text strings of Paths-->
    <DataTemplate DataType="{x:Type local:Photo}">
        <Border Margin="3">
            <Image Source="{Binding Source}"/>
        </Border>
    </DataTemplate>
</Window.Resources>

DataType プロパティは StyleTargetType プロパティに似ていることに注意してください。Notice that the DataType property is similar to the TargetType property of the Style. DataTemplate がリソース セクションにある場合、DataType プロパティを型に指定して x:Key を省略すると、その型が出現するたびに DataTemplate が適用されます。If your DataTemplate is in the resources section, when you specify the DataType property to a type and omit an x:Key, the DataTemplate is applied whenever that type appears. 常に、DataTemplatex:Key を割り当ててから、それを ItemTemplate プロパティや ContentTemplate プロパティなど、DataTemplate 型を取るプロパティの StaticResource として設定することもできます。You always have the option to assign the DataTemplate with an x:Key and then set it as a StaticResource for properties that take DataTemplate types, such as the ItemTemplate property or the ContentTemplate property.

基本的に、上記の例の DataTemplate は、Photo オブジェクトがあるときは必ず、Border 内の Image として表示するように定義しています。Essentially, the DataTemplate in the above example defines that whenever there is a Photo object, it should appear as an Image within a Border. この DataTemplate を使用すると、アプリは次のようになります。With this DataTemplate, our app now looks like this.

写真の画像

データ テンプレートのモデルでは、その他の機能を提供します。The data templating model provides other features. たとえば、MenuTreeView などの HeaderedItemsControl 型を使用して他のコレクションを含むコレクション データを表示する場合は、HierarchicalDataTemplate があります。For example, if you are displaying collection data that contains other collections using a HeaderedItemsControl type such as a Menu or a TreeView, there is the HierarchicalDataTemplate. もう 1 つのデータ テンプレート機能は DataTemplateSelector です。これを使用すると、カスタム ロジックに基づいて、使用する DataTemplate を選択することができます。Another data templating feature is the DataTemplateSelector, which allows you to choose a DataTemplate to use based on custom logic. 詳細については、「Data Templating Overview」を参照してください。ここでは、さまざまなデータ テンプレート機能を詳しく説明します。For more information, see Data Templating Overview, which provides a more in-depth discussion of the different data templating features.

トリガーTriggers

トリガーは、プロパティ値が変更されたときまたはイベントが発生したときに、プロパティを設定するかまたはアニメーションなどのアクションを開始します。A trigger sets properties or starts actions, such as an animation, when a property value changes or when an event is raised. StyleControlTemplate、および DataTemplate はすべて、一連のトリガーを含むことができる Triggers プロパティ備えています。Style, ControlTemplate, and DataTemplate all have a Triggers property that can contain a set of triggers. トリガーにはいくつかの種類があります。There are several types of triggers.

PropertyTriggerPropertyTriggers

プロパティの値を設定したりプロパティの値に基づいてアクションを開始したりする Trigger は、プロパティ トリガーと呼ばれます。A Trigger that sets property values or starts actions based on the value of a property is called a property trigger.

プロパティ トリガーを使用する方法を示すために、選択されていない限り、各 ListBoxItem を部分的に透明にすることができます。To demonstrate how to use property triggers, you can make each ListBoxItem partially transparent unless it is selected. 次のスタイルは、ListBoxItemOpacity 値を 0.5 に設定します。The following style sets the Opacity value of a ListBoxItem to 0.5. ただし、IsSelected プロパティが true の場合、Opacity1.0 に設定されます。When the IsSelected property is true, however, the Opacity is set to 1.0.

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

    <Style TargetType="ListBoxItem">
        <Setter Property="Opacity" Value="0.5" />
        <Setter Property="MaxHeight" Value="75" />
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Trigger.Setters>
                    <Setter Property="Opacity" Value="1.0" />
                </Trigger.Setters>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

この例は、Trigger を使用してプロパティ値を設定しますが、Trigger クラスには、トリガーがアクションを実行できるようにする EnterActions および ExitActions プロパティも含まれていることに注意してください。This example uses a Trigger to set a property value, but note that the Trigger class also has the EnterActions and ExitActions properties that enable a trigger to perform actions.

ListBoxItemMaxHeight プロパティが 75 に設定されていることに注意してください。Notice that the MaxHeight property of the ListBoxItem is set to 75. 次の図では、3 番目の項目が選択されている項目です。In the following illustration, the third item is the selected item.

スタイル設定された ListView

Eventtrigger とストーリー ボードEventTriggers and Storyboards

別の種類のトリガーは EventTrigger です。これは、イベントの発生に基づいて一連のアクションを開始します。Another type of trigger is the EventTrigger, which starts a set of actions based on the occurrence of an event. たとえば、次の EventTrigger オブジェクトは、マウス ポインターが ListBoxItem に入ると、MaxHeight プロパティが 0.2 秒間 90 の値にアニメーション化されることを指定しています。For example, the following EventTrigger objects specify that when the mouse pointer enters the ListBoxItem, the MaxHeight property animates to a value of 90 over a 0.2 second period. この項目からマウスを遠ざけると、1 秒間、元の値に戻ります。When the mouse moves away from the item, the property returns to the original value over a period of 1 second. MouseLeave アニメーションに対して To 値を指定する必要がないことに注意してください。Note how it is not necessary to specify a To value for the MouseLeave animation. これは、アニメーションが元の値を追跡できるからです。This is because the animation is able to keep track of the original value.

<Style.Triggers>
    <Trigger Property="IsSelected" Value="True">
        <Trigger.Setters>
            <Setter Property="Opacity" Value="1.0" />
        </Trigger.Setters>
    </Trigger>
    <EventTrigger RoutedEvent="Mouse.MouseEnter">
        <EventTrigger.Actions>
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation
                        Duration="0:0:0.2"
                        Storyboard.TargetProperty="MaxHeight"
                        To="90"  />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger.Actions>
    </EventTrigger>
    <EventTrigger RoutedEvent="Mouse.MouseLeave">
        <EventTrigger.Actions>
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation
                        Duration="0:0:1"
                        Storyboard.TargetProperty="MaxHeight"  />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger.Actions>
    </EventTrigger>
</Style.Triggers>

詳細については、「ストーリーボードの概要」を参照してください。For more information, see the Storyboards overview.

次の図では、マウスは3 番目の項目を指しています。In the following illustration, the mouse is pointing to the third item.

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

MultiTriggers、DataTriggers、および MultiDataTriggersMultiTriggers, DataTriggers, and MultiDataTriggers

TriggerEventTrigger に加えて、他の種類のトリガーがあります。In addition to Trigger and EventTrigger, there are other types of triggers. MultiTrigger を使用すると、複数の条件に基づいてプロパティ値を設定できます。MultiTrigger allows you to set property values based on multiple conditions. 条件のプロパティがデータバインドされている場合は、DataTriggerMultiDataTrigger を使用します。You use DataTrigger and MultiDataTrigger when the property of your condition is data-bound.

表示状態Visual States

コントロールは常に、特定の 状態 にあります。Controls are always in a specific state. たとえば、マウスがコントロールの画面上を移動しているとき、そのコントロールは一般的な MouseOver の状態であると見なされます。For example, when the mouse moves over the surface of a control, the control is considered to be in a common state of MouseOver. 特定の状態のないコントロールは、一般的な Normal 状態であると見なされます。A control without a specific state is considered to be in the common Normal state. 状態はグループに分割され、前に述べた状態は CommonStates という状態グループの一部です。States are broken into groups, and the previously mentioned states are part of the state group CommonStates. ほとんどのコントロールには、CommonStatesFocusStates の 2 つの状態グループがあります。Most controls have two state groups: CommonStates and FocusStates. コントロールに適用される各状態グループのコントロールは、CommonStates.MouseOverFocusStates.Unfocused など、常に各グループの 1 つの状態になります。Of each state group applied to a control, a control is always in one state of each group, such as CommonStates.MouseOver and FocusStates.Unfocused. ただし、コントロールは、CommonStates.NormalCommonStates.Disabled など、同じグループ内で 2 つの異なる状態であることはできません。However, a control can't be in two different states within the same group, such as CommonStates.Normal and CommonStates.Disabled. 大部分のコントロールが認識して使用する状態の表を次に示します。Here is a table of states most controls recognize and use.

VisualState 名VisualState Name VisualStateGroup 名VisualStateGroup Name 説明Description
標準Normal CommonStatesCommonStates 既定の状態です。The default state.
MouseOverMouseOver CommonStatesCommonStates マウス ポインターがコントロール上に配置されています。The mouse pointer is positioned over the control.
押されているPressed CommonStatesCommonStates コントロールが押されています。The control is pressed.
無効Disabled CommonStatesCommonStates コントロールが無効になっています。The control is disabled.
フォーカスされているFocused FocusStatesFocusStates コントロールにフォーカスがあります。The control has focus.
フォーカスされていないUnfocused FocusStatesFocusStates コントロールにフォーカスがありません。The control does not have focus.

コントロール テンプレートのルート要素に System.Windows.VisualStateManager を定義することで、コントロールが特定の状態になったときにアニメーションをトリガーできます。By defining a System.Windows.VisualStateManager on the root element of a control template, you can trigger animations when a control enters a specific state. VisualStateManager は、監視する VisualStateGroupVisualState の組み合わせを宣言します。The VisualStateManager declares which combinations of VisualStateGroup and VisualState to watch. コントロールが監視している状態になると、VisaulStateManager によって定義されたアニメーションが開始されます。When the control enters a watched state, the animation defined by the VisaulStateManager is started.

たとえば、次の XAML コードは、CommonStates.MouseOver 状態を監視して、backgroundElement という名前の要素の塗りつぶしの色をアニメーション化します。For example, the following XAML code watches the CommonStates.MouseOver state to animate the fill color of the element named backgroundElement. コントロールが CommonStates.Normal 状態に戻ると、backgroundElement という名前の要素の塗りつぶしの色が復元されます。When the control returns to the CommonStates.Normal state, the fill color of the element named backgroundElement is restored.

<ControlTemplate x:Key="roundbutton" TargetType="Button">
    <Grid>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup Name="CommonStates">
                <VisualState Name="Normal">
                    <ColorAnimation Storyboard.TargetName="backgroundElement"
                                    Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
                                    To="{TemplateBinding Background}"
                                    Duration="0:0:0.3"/>
                </VisualState>
                <VisualState Name="MouseOver">
                    <ColorAnimation Storyboard.TargetName="backgroundElement"
                                    Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"
                                    To="Yellow"
                                    Duration="0:0:0.3"/>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

        ...

ストーリーボードの詳細については、「ストーリーボードの概要」を参照してください。For more information about storyboards, see Storyboards Overview.

共有リソースとテーマShared resources and themes

標準的な WPF アプリには、アプリ全体で適用される複数の UI リソースがある場合があります。A typical WPF app might have multiple UI resources that are applied throughout the app. ひとまとめにして、この一連のリソースをアプリのテーマと見なすことができます。Collectively, this set of resources can be considered the theme for the app. WPF では、ResourceDictionary クラスとしてカプセル化されているリソース ディクショナリを使用して UI リソースをテーマとしてパッケージ化することをサポートしています。WPF provides support for packaging UI resources as a theme by using a resource dictionary that is encapsulated as the ResourceDictionary class.

WPF のテーマは、要素のビジュアルをカスタマイズするために WPF が公開しているスタイルとテンプレートのメカニズムを使用して定義されます。WPF themes are defined by using the styling and templating mechanism that WPF exposes for customizing the visuals of any element.

WPF のテーマのリソースは、埋め込みリソース ディクショナリに格納されます。WPF theme resources are stored in embedded resource dictionaries. これらのリソース ディクショナリは署名されたアセンブリ内に埋め込む必要があり、コード自体と同じアセンブリまたはサイド バイ サイド アセンブリで埋め込むことができます。These resource dictionaries must be embedded within a signed assembly, and can either be embedded in the same assembly as the code itself or in a side-by-side assembly. WPF コントロールを含むアセンブリである PresentationFramework.dll の場合、テーマのリソースは、一連の side-by-sede アセンブリに含まれます。For PresentationFramework.dll, the assembly that contains WPF controls, theme resources are in a series of side-by-side assemblies.

テーマは、要素のスタイルを検索するときに最後に検索する場所になります。The theme becomes the last place to look when searching for the style of an element. 通常、検索を行うには、まず適切なリソースを探索して要素ツリーをたどり、次にアプリのリソース コレクションを調べ、最後にシステムに対してクエリを実行します。Typically, the search will begin by walking up the element tree searching for an appropriate resource, then look in the app resource collection and finally query the system. こうすることで、アプリ開発者は、テーマに到達する前に、ツリーまたはアプリのレベルで任意のオブジェクトのスタイルを再定義できます。This gives app developers a chance to redefine the style for any object at the tree or app level before reaching the theme.

リソース ディクショナリは、複数のアプリ間でのテーマの再利用を可能にする個別ファイルとして定義できます。You can define resource dictionaries as individual files that enable you to reuse a theme across multiple apps. また、同じ種類のリソースだが値が異なる複数のリソース ディクショナリを定義して、交換できるテーマを作成することもできます。You can also create swappable themes by defining multiple resource dictionaries that provide the same types of resources but with different values. アプリをスキニングする場合、これらのスタイルまたはその他のリソースをアプリ レベルで再定義することをお勧めします。Redefining these styles or other resources at the app level is the recommended approach for skinning an app.

スタイルおよびテンプレートを含む一連のリソースをアプリ間で共有するには、XAML ファイルを作成し、shared.xaml ファイルへの参照を含む ResourceDictionary を定義します。To share a set of resources, including styles and templates, across apps, you can create a XAML file and define a ResourceDictionary that includes reference to a shared.xaml file.

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

これは、一連のスタイルとブラシのリソースが含まれた ResourceDictionary をそれ自体が定義している shared.xaml の共有です。これにより、アプリのコントロールに一貫した外観を持たせることができます。It is the sharing of shared.xaml, which itself defines a ResourceDictionary that contains a set of style and brush resources, that enables the controls in an app to have a consistent look.

詳細については、「マージされたリソース ディクショナリ」を参照してください。For more information, see Merged resource dictionaries.

カスタム コントロールのテーマを作成する場合は、「コントロールの作成の概要」の「テーマ レベルでのリソースの定義」セクションを参照してください。If you are creating a theme for your custom control, see the Defining resources at the theme level section of the Control authoring overview.

関連項目See also