ControlTemplate の作成による既存のコントロールの外観のカスタマイズCustomizing the Appearance of an Existing Control by Creating a ControlTemplate

ControlTemplate 、コントロールの視覚的な構造と視覚的な動作を指定します。A ControlTemplate specifies the visual structure and visual behavior of a control. コントロールの外観は、新しいControlTemplateを指定することによってカスタマイズできます。You can customize the appearance of a control by giving it a new ControlTemplate. ControlTemplate作成すると、既存のコントロールの外観は、その機能を変更せずに置き換えることができます。When you create a ControlTemplate, you replace the appearance of an existing control without changing its functionality. たとえば、既定の四角形の形ではなく、アプリケーションのボタンを丸めることができますが、ボタンはイベントをClick発生させます。For example, you can make the buttons in your application round instead of the default square shape, but the button will still raise the Click event.

このトピックControlTemplateでは、のさまざまな部分について説明し、 Buttonの簡単ControlTemplateなを作成する方法と、コントロールのコントロールコントラクトを理解してその外観をカスタマイズできるようにする方法について説明します。This topic explains the various parts of a ControlTemplate, demonstrates creating a simple ControlTemplate for a Button, and explains how to understand the control contract of a control so that you can customize its appearance. ControlTemplateXAMLXAMLを作成するので、コードを記述することなく、コントロールの外観を変更できます。Because you create a ControlTemplate in XAMLXAML, you can change a control's appearance without writing any code. また、カスタム コントロール テンプレートを作成するために、Microsoft Expression Blend などのデザイナーを使用することもできます。You can also use a designer, such as Microsoft Expression Blend, to create custom control templates. このトピックでは、 XAMLXAMLの外観Buttonをカスタマイズするの例を示し、トピックの最後にある完全な例を示します。This topic shows examples in the XAMLXAML that customize the appearance of a Button and lists the complete example at the end of the topic. Expression Blend の使用方法の詳細については、「テンプレートをサポートするコントロールのスタイル処理」を参照してください。For more information about using Expression Blend, see Styling a control that supports templates.

次の図は、 ButtonこのトピックでControlTemplate作成したを使用するを示しています。The following illustrations show a Button that uses the ControlTemplate that is created in this topic.

カスタムコントロールテンプレートを持つボタン。A button with a custom control template.
カスタム コントロール テンプレートを使用しているボタンA button that uses a custom control template

赤い枠線付きのボタン。A button with a red border.
カスタム コントロール テンプレートを使用したボタンにマウス ポインターを置いた状態A button that uses a custom control template and has the mouse pointer over it

必須コンポーネントPrerequisites

このトピックは、「コントロール」で説明したコントロールとスタイルの作成方法および使用方法を理解していることを前提としています。This topic assumes that you understand how to create and use controls and styles as discussed in Controls. このトピックで説明する概念は、 Control UserControlを除き、クラスを継承する要素に適用されます。The concepts discussed in this topic apply to elements that inherit from the Control class, except for the UserControl. ControlTemplateUserControlに適用することはできません。You cannot apply a ControlTemplate to a UserControl.

ControlTemplate の作成が必要な場合When You Should Create a ControlTemplate

コントロールにはBackground、、 Foreground FontFamily、などの多くのプロパティがあり、コントロールの外観のさまざまな側面を指定するように設定できますが、これらのプロパティを設定することによって行うことができる変更は制限されます。Controls have many properties, such as Background, Foreground, and FontFamily, that you can set to specify different aspects of the control's appearance, but the changes that you can make by setting these properties are limited. たとえば、でForeground は、FontStyleプロパティを blue に、italic を italic に設定できます。CheckBoxFor example, you can set the Foreground property to blue and FontStyle to italic on a CheckBox.

コントロール用の新しいControlTemplateを作成する機能がない場合、すべてのベースのアプリケーションWPFWPFのすべてのコントロールの全般的な外観は同じになります。これにより、カスタムのルックアンドフィールでアプリケーションを作成する機能が制限されます。Without the ability to create a new ControlTemplate for controls, all controls in every WPFWPF-based application would have the same general appearance, which would limit the ability to create an application with a custom look and feel. 既定では、 CheckBoxすべての特性が類似しています。By default, every CheckBox has similar characteristics. たとえば、のCheckBoxコンテンツは常に選択インジケーターの右側にあり、チェックマークはが選択されてCheckBoxいることを示すために常に使用されます。For example, the content of the CheckBox is always to the right of the selection indicator, and the check mark is always used to indicate that the CheckBox is selected.

コントロールの他ControlTemplateのプロパティが行う設定よりも、コントロールの外観をカスタマイズする場合は、を作成します。You create a ControlTemplate when you want to customize the control's appearance beyond what setting the other properties on the control will do. CheckBox例では、チェックボックスの内容を選択インジケーターの上に配置し、 CheckBoxが選択されていることを示す X を使用するとします。In the example of the CheckBox, suppose that you want the content of the check box to be above the selection indicator and you want an X to indicate that the CheckBox is selected. これらControlTemplateの変更は、 CheckBoxので指定します。You specify these changes in the ControlTemplate of the CheckBox.

次の図は、 CheckBox既定値ControlTemplateを使用するを示しています。The following illustration shows a CheckBox that uses a default ControlTemplate.

既定のコントロールテンプレートを含むチェックボックス。A checkbox with the default control template.
既定のコントロール テンプレートを使用する CheckBoxA CheckBox that uses the default control template

次の図は、 CheckBoxカスタムControlTemplateを使用して、選択インジケーターのCheckBox上に上の内容を配置し、 CheckBoxが選択されている場合に X を表示するを示しています。The following illustration shows a CheckBox that uses a custom ControlTemplate to place the content of the CheckBox above the selection indicator and displays an X when the CheckBox is selected.

カスタムコントロールテンプレートを含むチェックボックス。A checkbox with a custom control template.
カスタム コントロール テンプレートを使用する CheckBoxA CheckBox that uses a custom control template

このサンプルののはControlTemplate比較的複雑であるため、このトピックではControlTemplate 、のを作成するためButtonの簡単な例を使用します。 CheckBoxThe ControlTemplate for the CheckBox in this sample is relatively complex, so this topic uses a simpler example of creating a ControlTemplate for a Button.

コントロールの視覚的な構造の変更Changing the Visual Structure of a Control

WPFWPFは、多くの場合、コントロールFrameworkElementは複合オブジェクトです。In WPFWPF, a control is often a composite FrameworkElement objects. を作成ControlTemplateするときに、オブジェクトFrameworkElementを結合して1つのコントロールを作成します。When you create a ControlTemplate, you combine FrameworkElement objects to build a single control. ControlTemplateは、ルート要素FrameworkElementとして1つだけを指定する必要があります。A ControlTemplate must have only one FrameworkElement as its root element. ルート要素には、通常FrameworkElement 、他のオブジェクトが含まれます。The root element usually contains other FrameworkElement objects. 複数のオブジェクトを組み合わせて、コントロールの視覚的な構造を構成します。The combination of objects makes up the control's visual structure.

次の例では、 ControlTemplate Buttonのカスタムを作成します。The following example creates a custom ControlTemplate for the Button. によって、 Buttonのビジュアル構造が作成されます。ControlTemplateThe ControlTemplate creates the visual structure of the Button. この例では、ボタンの上にマウス ポインターを移動しても、ボタンをクリックしても、その外観は変化しません。This example does not change the button's appearance when you move the mouse pointer over it or click it. 状態に応じて外観が変化するボタンについては、このトピックで後述します。Changing the button's appearance when it is in a different state is discussed later in this topic.

この例では、以下のパーツで視覚的な構造を構成しています。In this example, the visual structure consists of the following parts:

<ControlTemplate TargetType="Button">
  <Border Name="RootElement">

    <!--Create the SolidColorBrush for the Background 
        as an object elemment and give it a name so 
        it can be referred to elsewhere in the
        control template.-->
    <Border.Background>
      <SolidColorBrush x:Name="BorderBrush" Color="Black"/>
    </Border.Background>

    <!--Create a border that has a different color
        by adding smaller grid. The background of 
        this grid is specificied by the button's 
        Background property.-->
    <Grid Margin="4" Background="{TemplateBinding Background}">

      <!--Use a ContentPresenter to display the Content of
          the Button.-->
      <ContentPresenter
        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
        Margin="4,5,4,4" />
    </Grid>

  </Border>
</ControlTemplate>

TemplateBinding を使用してコントロールのプロパティの機能を維持する方法Preserving the Functionality of a Control's Properties by Using TemplateBinding

新しいControlTemplateを作成する場合でも、パブリックプロパティを使用してコントロールの外観を変更することをお勧めします。When you create a new ControlTemplate, you still might want to use the public properties to change the control's appearance. TemplateBindingマークアップ拡張機能は、にある要素のプロパティを、 ControlTemplateコントロールで定義されているパブリックプロパティにバインドします。The TemplateBinding markup extension binds a property of an element that is in the ControlTemplate to a public property that is defined by the control. TemplateBinding を使用すると、コントロールのプロパティをテンプレートのパラメーターとして機能させることができます。When you use TemplateBinding, you enable properties on the control to act as parameters to the template. つまり、コントロールのプロパティを設定すると、その値は TemplateBinding が機能している要素に渡されます。That is, when a property on a control is set, that value is passed on to the element that has the TemplateBinding on it.

次の例では、前の例の部分を繰り返します。この例では、 TemplateBindingマークアップ拡張機能ControlTemplateを使用して、にある要素のプロパティを、ボタンで定義されているパブリックプロパティにバインドしています。The following example repeats the part of the preceding example that uses the TemplateBinding markup extension to bind properties of elements that are in the ControlTemplate to public properties that are defined by the button.

<Grid Margin="4" Background="{TemplateBinding Background}">

  <!--Use a ContentPresenter to display the Content of
      the Button.-->
  <ContentPresenter
    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
    Margin="4,5,4,4" />
</Grid>

この例では、 GridPanel.BackgroundプロパティテンプレートがにControl.Backgroundバインドされています。In this example, the Grid has its Panel.Background property template bound to Control.Background. Panel.Backgroundテンプレートにバインドされているため、同じControlTemplateを使用する複数のボタンControl.Backgroundを作成し、各ボタンでを異なる値に設定できます。Because Panel.Background is template bound, you can create multiple buttons that use the same ControlTemplate and set the Control.Background to different values on each button. Control.BackgroundControlTemplate要素のプロパティにテンプレートバインドされていない場合、ボタンControl.Backgroundのを設定しても、ボタンの外観には影響しません。If Control.Background was not template bound to a property of an element in the ControlTemplate, setting the Control.Background of a button would have no impact on the button's appearance.

2 つのプロパティの名前は同じである必要はありません。Note that the names of the two properties do not need to be identical. 前の例Control.HorizontalContentAlignmentでは、のFrameworkElement.HorizontalAlignmentプロパティButtonは、 ContentPresenterのプロパティにバインドされています。In the preceding example, the Control.HorizontalContentAlignment property of the Button is template bound to the FrameworkElement.HorizontalAlignment property of the ContentPresenter. これにより、ボタンのコンテンツを水平方向に配置できます。This enables the content of the button to be positioned horizontally. ContentPresenterにはという名前HorizontalContentAlignmentのプロパティはありませんがFrameworkElement.HorizontalAlignment Control.HorizontalContentAlignment 、にバインドできます。ContentPresenter does not have a property named HorizontalContentAlignment, but Control.HorizontalContentAlignment can be bound to FrameworkElement.HorizontalAlignment. プロパティをテンプレート バインディングするときは、ターゲットとソースのプロパティが同じ型であることを確認してください。When you template bind a property, be sure that the target and source properties are the same type.

クラスControlは、コントロールテンプレートが設定されたときにコントロールに影響を与えるために使用する必要があるいくつかのプロパティを定義します。The Control class defines several properties that must be used by the control template to have an effect on the control when they are set. ControlTemplateプロパティを使用する方法は、プロパティによって異なります。How the ControlTemplate uses the property depends on the property. では、次のいずれかの方法でプロパティを使用する必要があります。ControlTemplateThe ControlTemplate must use the property in one of the following ways:

次の表に、 Controlクラスからコントロールによって継承されるビジュアルプロパティの一覧を示します。The following table lists the visual properties inherited by a control from the Control class. また、コントロールの既定のコントロール テンプレートで継承されたプロパティ値を使用するかどうか、テンプレート バインディングする必要があるかどうかも示します。It also indicates whether the default control template of a control uses the inherited property value or if it must be template bound.

プロパティProperty 使用するメソッドUsage method
Background テンプレート バインディングTemplate binding
BorderThickness テンプレート バインディングTemplate binding
BorderBrush テンプレート バインディングTemplate binding
FontFamily プロパティの継承またはテンプレート バインディングProperty inheritance or template binding
FontSize プロパティの継承またはテンプレート バインディングProperty inheritance or template binding
FontStretch プロパティの継承またはテンプレート バインディングProperty inheritance or template binding
FontWeight プロパティの継承またはテンプレート バインディングProperty inheritance or template binding
Foreground プロパティの継承またはテンプレート バインディングProperty inheritance or template binding
HorizontalContentAlignment テンプレート バインディングTemplate binding
Padding テンプレート バインディングTemplate binding
VerticalContentAlignment テンプレート バインディングTemplate binding

このテーブルには、 Controlクラスから継承されたビジュアルプロパティのみが表示されます。The table lists only the visual properties inherited from the Control class. テーブルに示されているプロパティとは別に、コントロールはDataContextLanguage、、およびTextDecorationsの各プロパティを親フレームワーク要素から継承することもあります。Apart from the properties listed in the table, a control may also inherit the DataContext, Language, and TextDecorations properties from the parent framework element.

またContentPresenterContentControlTemplate ContentTemplateContentControlである場合、はプロパティとプロパティに自動的にバインドされます。ContentPresenterAlso, if the ContentPresenter is in the ControlTemplate of a ContentControl, the ContentPresenter will automatically bind to the ContentTemplate and Content properties. ControlTemplate Items同様に、 ItemsPresenterItemsControlに含まれるは、プロパティとプロパティに自動的にバインドされます。ItemsPresenterLikewise, an ItemsPresenter that is in the ControlTemplate of an ItemsControl will automatically bind to the Items and ItemsPresenter properties.

次の例では、前の例ControlTemplateで定義したを使用する2つのボタンを作成します。The following example creates two buttons that use the ControlTemplate defined in the preceding example. この例ではBackgroundForeground各ボタンFontSizeの、、およびの各プロパティを設定します。The example sets the Background, Foreground, and FontSize properties on each button. プロパティのBackground設定は、 ControlTemplateテンプレートがにバインドされているため、効果があります。Setting the Background property has an effect because it is template bound in the ControlTemplate. ForegroundプロパティとFontSizeプロパティがテンプレートにバインドされていない場合でも、値が継承されるため、設定が影響を受けます。Even though the Foreground and FontSize properties are not template bound, setting them has an effect because their values are inherited.

<StackPanel>
  <Button Style="{StaticResource newTemplate}" 
          Background="Navy" Foreground="White" FontSize="14"
          Content="Button1"/>

  <Button Style="{StaticResource newTemplate}" 
          Background="Purple" Foreground="White" FontSize="14"
          Content="Button2" HorizontalContentAlignment="Left"/>
</StackPanel>

前の例では、次の図のような出力を生成します。The preceding example produces output that is similar to the following illustration.

青と紫色の2つのボタン。Two buttons, one blue and one purple.
背景色が異なる 2 つのボタンTwo buttons with different background colors

状態に応じたコントロールの外観の変化Changing the Appearance of a Control Depending on Its State

既定の外観のボタンと前の例のボタンの違いは、既定のボタンが別の状態になったときにわずかに変化することです。The difference between a button with its default appearance and the button in the preceding example is that the default button subtly changes when it is in different states. たとえば、ボタンをクリックしたときやマウス ポインターをボタンの上に置いたときに、既定のボタンは外観が変化します。For example, the default button's appearance changes when the button is pressed, or when the mouse pointer is over the button. ControlTemplateはコントロールの機能を変更しませんが、コントロールの視覚的な動作を変更します。Although the ControlTemplate does not change the functionality of a control, it does change the control's visual behavior. 視覚的な動作とは、コントロールが特定の状態にあるときの外観を指しています。A visual behavior describes the control appearance when it is in a certain state. コントロールの機能と視覚的な動作の違いを理解するために、ボタンの例について考えてみます。To understand the difference between the functionality and visual behavior of a control, consider the button example. ボタンの機能は、クリックされClickたときにイベントを発生させますが、ボタンの視覚的な動作は、ポイントまたは押されたときの外観を変更することです。The button's functionality is to raise the Click event when it is clicked, but the button's visual behavior is to change its appearance when it is pointed to or pressed.

オブジェクトをVisualState使用して、コントロールが特定の状態にあるときの外観を指定します。You use VisualState objects to specify the appearance of a control when it is in a certain state. には、 Storyboard内のControlTemplate要素の外観を変更するが含まれています。VisualStateA VisualState contains a Storyboard that changes the appearance of the elements that are in the ControlTemplate. コントロールのロジックがを使用VisualStateManagerして状態を変更するため、このようなコードを記述する必要はありません。You do not have to write any code to make this occur because the control's logic changes state by using the VisualStateManager. コントロールがVisualState.Nameプロパティによって指定された状態になるとStoryboard 、が開始されます。When the control enters the state that is specified by the VisualState.Name property, the Storyboard begins. コントロールが状態を終了すると、 Storyboardは停止します。When the control exits the state, the Storyboard stops.

次の例は、 VisualStateマウスポインターが上にあるButtonときのの外観を変更するを示しています。The following example shows the VisualState that changes the appearance of a Button when the mouse pointer is over it. StoryboardBorderBrushの色を変更することによって、ボタンの境界線の色を変更します。The Storyboard changes the button's border color by changing the color of the BorderBrush. このトピックの冒頭にControlTemplateある例を参照すると、 SolidColorBrushがのにBackground Border割り当てらBorderBrushれているの名前であることを思い出してください。If you refer to the ControlTemplate example at the beginning of this topic, you will recall that BorderBrush is the name of the SolidColorBrush that is assigned to the Background of the Border.

<!--Change the border of the button to red when the
    mouse is over the button.-->
<VisualState x:Name="MouseOver">
  <Storyboard>
    <ColorAnimation Storyboard.TargetName="BorderBrush"     
                    Storyboard.TargetProperty="Color"
                    To="Red" />

  </Storyboard>
</VisualState>

このコントロールは、コントロール コントラクトの一部として状態を定義する役割を果たします。詳細については、このトピックの「コントロール コントラクトについて理解しその他のコントロールをカスタマイズする方法」で後述します。The control is responsible for defining the states as part of its control contract, which is discussed in detail in Customizing Other Controls by Understanding the Control Contract later in this topic. に指定されている状態を次の表Buttonに示します。The following table lists the states that are specified for the Button.

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.
DisabledDisabled CommonStatesCommonStates コントロールが無効になっています。The control is disabled.
フォーカスされているFocused FocusStatesFocusStates コントロールにフォーカスがあります。The control has focus.
フォーカスされていないUnfocused FocusStatesFocusStates コントロールにフォーカスがありません。The control does not have focus.

Button 2 つの状態グループをCommonStates定義しますNormalMouseOver PressedグループにはDisabled 、、、およびの各状態が含まれます。The Button defines two state groups: the CommonStates group contains the Normal, MouseOver, Pressed, and Disabled states. FocusStates グループには、Focused 状態と Unfocused 状態が含まれます。The FocusStates group contains the Focused and Unfocused states. 同じ状態グループ内の状態を同時に複数指定することはできません。States in the same state group are mutually exclusive. コントロールが取り得る状態は、常に 1 グループにつき 1 つです。The control is always in exactly one state per group. Buttonたとえば、は、マウスポインターが上にない場合でもフォーカスを持つことができるのでFocused 、状態のButtonMouseOverPressed、のいずれNormalかの状態になります。For example, a Button can have focus even when the mouse pointer is not over it, so a Button in the Focused state can be in the MouseOver, Pressed, or Normal state.

オブジェクトにVisualStateオブジェクトをVisualStateGroup追加します。You add VisualState objects to VisualStateGroup objects. 添付VisualStateGroupsプロパティVisualStateGroupにオブジェクトを追加します。You add VisualStateGroup objects to the VisualStateGroups attached property. 次の例ではVisualStateNormalMouseOver PressedCommonStatesおよびの各状態のオブジェクトを定義しています。これらはすべてグループに含まれています。The following example defines the VisualState objects for the Normal, MouseOver, and Pressed states, which are all in the CommonStates group. Name それぞれVisualStateのは、前の表の名前と一致します。The Name of each VisualState matches the name in the preceding table. Disabled の状態および FocusStates グループの状態は、例を簡潔にするために省略していますが、このトピックの最後で紹介している完全なコード例には含まれています。The Disabled state and the states in the FocusStates group are omitted to keep the example short, but they are included in the entire example at the end of this topic.

注意

VisualStateGroups ルートFrameworkElementで添付プロパティを必ず設定してください。 ControlTemplateBe sure to set the VisualStateGroups attached property on the root FrameworkElement of the ControlTemplate.

<ControlTemplate TargetType="Button">
  <Border Name="RootElement">

    <VisualStateManager.VisualStateGroups>

      <!--Define the states and transitions for the common states.
          The states in the VisualStateGroup are mutually exclusive to
          each other.-->
      <VisualStateGroup x:Name="CommonStates">

        <!--The Normal state is the state the button is in
            when it is not in another state from this VisualStateGroup.-->
        <VisualState x:Name="Normal" />

        <!--Change the SolidColorBrush, BorderBrush, to red when the
            mouse is over the button.-->
        <VisualState x:Name="MouseOver">
          <Storyboard>
            <ColorAnimation Storyboard.TargetName="BorderBrush" 
                            Storyboard.TargetProperty="Color" 
                            To="Red" />
          </Storyboard>
        </VisualState>

        <!--Change the SolidColorBrush, BorderBrush, to Transparent when the
            button is pressed.-->
        <VisualState x:Name="Pressed">
          <Storyboard>
            <ColorAnimation Storyboard.TargetName="BorderBrush" 
                            Storyboard.TargetProperty="Color"
                            To="Transparent"/>
          </Storyboard>
        </VisualState>

        <!--The Disabled state is omitted for brevity.-->
      </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

    <Border.Background>
      <SolidColorBrush x:Name="BorderBrush" Color="Black"/>
    </Border.Background>

    <Grid Background="{TemplateBinding Background}" Margin="4">
      <ContentPresenter
        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
        Margin="4,5,4,4" />
    </Grid>
  </Border>
</ControlTemplate>

前の例では、次の図のような出力を生成します。The preceding example produces output that is similar to the following illustrations.

カスタムコントロールテンプレートを持つボタン。A button with a custom control template.
通常状態のカスタム コントロール テンプレートを使用しているボタンA button that uses a custom control template in the normal state

赤い枠線付きのボタン。A button with a red border.
マウス オーバー状態のカスタム コントロール テンプレートを使用しているボタンA button that uses a custom control template in the mouse over state

押されたボタンでは、境界線は透明になります。The border is transparent on a pressed button.
押された状態のカスタム コントロール テンプレートを使用しているボタンA button that uses a custom control template in the pressed state

WPFWPF に付属するコントロールの視覚的な状態については、「コントロールのスタイルとテンプレート」を参照してください。To find the visual states for controls that are included with WPFWPF, see Control Styles and Templates.

状態間を遷移するときのコントロールの動作の指定Specifying the Behavior of a Control When It Transitions Between States

前の例では、ボタンをクリックしたときにもボタンの外観が変化しましたが、ボタンを 1 秒間押したままにしない限り、効果を確認できません。In the preceding example, the appearance of the button also changes when the user clicks it, but unless the button is pressed for a full second, the user does not see the effect. 既定では、アニメーションが開始されるまでに 1 秒かかります。By default, the animation takes one second to occur. ユーザーがボタンをクリックしてすぐに解放する可能性が高いため、を既定の状態ControlTemplateのままにしておくと、視覚的なフィードバックが有効になりません。Because users are likely to click and release a button in much less time, the visual feedback will not be effective if you leave the ControlTemplate in its default state.

にオブジェクトを追加VisualTransitionすることによって、 ControlTemplateコントロールをある状態から別の状態にスムーズに遷移させるために、アニメーションが発生するまでの時間を指定できます。You can specify the amount of time that it takes an animation to occur to smoothly transition a control from one state to another by adding VisualTransition objects to the ControlTemplate. を作成VisualTransitionするときは、次のいずれかまたは複数を指定します。When you create a VisualTransition, you specify one or more of the following:

  • 状態間の遷移を開始するまでに要する時間。The time it takes for a transition between states to occur.

  • 遷移時に発生するコントロールの外観への追加の変更。Additional changes in the control's appearance that occur at the time of the transition.

  • VisualTransitionがに適用される状態。Which states the VisualTransition is applied to.

遷移の継続時間の指定Specifying the Duration of a Transition

遷移の実行時間を指定するには、 GeneratedDurationプロパティを設定します。You can specify how long a transition takes by setting the GeneratedDuration property. 前の例にはVisualState 、ボタンが押されたときにボタンの境界線が透明になることを指定するがありますが、ボタンがすぐに押されて解放されると、アニメーションの処理に時間がかかりすぎます。The preceding example has a VisualState that specifies that the button's border becomes transparent when the button is pressed, but the animation takes too long to be noticeable if the button is quickly pressed and released. VisualTransition使用すると、コントロールが押された状態に遷移するまでの時間を指定できます。You can use a VisualTransition to specify the amount of time it takes the control to transition into the pressed state. 次の例では、コントロールが押された状態になるのに要する時間を 1/100 秒に指定しています。The following example specifies that the control takes one hundredth of a second to go into the pressed state.

<!--Take one hundredth of a second to transition to the
    Pressed state.-->
<VisualTransition To="Pressed" 
                  GeneratedDuration="0:0:0.01" />

遷移時にコントロールの外観の変更を指定する方法Specifying Changes to the Control's Appearance During a Transition

VisualTransition 、コントロールStoryboardが状態間を遷移するときに開始するを格納します。The VisualTransition contains a Storyboard that begins when the control transitions between states. たとえば、コントロールが MouseOver 状態から Normal 状態に遷移する場合に、特定のアニメーションが実行されるように指定できます。For example, you can specify that a certain animation occurs when the control transitions from the MouseOver state to the Normal State. 次の例ではVisualTransition 、ユーザーがマウスポインターをボタンの上に移動したときに、ボタンの境界線が青に変わり、黄色の場合は1.5 秒で黒に変更されることを指定するを作成します。The following example creates a VisualTransition that specifies that when the user moves the mouse pointer away from the button, the button's border changes to blue, then to yellow, then to black in 1.5 seconds.

<!--Take one and a half seconds to transition from the
    MouseOver state to the Normal state. 
    Have the SolidColorBrush, BorderBrush, fade to blue, 
    then to yellow, and then to black in that time.-->
<VisualTransition From="MouseOver" To="Normal" 
                      GeneratedDuration="0:0:1.5">
  <Storyboard>
    <ColorAnimationUsingKeyFrames
      Storyboard.TargetProperty="Color"
      Storyboard.TargetName="BorderBrush"
      FillBehavior="HoldEnd" >

      <ColorAnimationUsingKeyFrames.KeyFrames>

        <LinearColorKeyFrame Value="Blue" 
          KeyTime="0:0:0.5" />
        <LinearColorKeyFrame Value="Yellow" 
          KeyTime="0:0:1" />
        <LinearColorKeyFrame Value="Black" 
          KeyTime="0:0:1.5" />

      </ColorAnimationUsingKeyFrames.KeyFrames>
    </ColorAnimationUsingKeyFrames>
  </Storyboard>
</VisualTransition>

VisualTransition を適用するタイミングの指定Specifying When a VisualTransition Is Applied

VisualTransition特定の状態にのみ適用されるように制限できます。また、コントロールが状態間を遷移するたびに適用することもできます。A VisualTransition can be restricted to apply to only certain states, or it can be applied any time the control transitions between states. VisualTransition前の例では、コントロールが状態Normal MouseOverから状態になると、が適用されますVisualTransition 。その前の例では、コントロールPressedが状態になるとが適用されます。In the preceding example, the VisualTransition is applied when the control goes from the MouseOver state to the Normal state; in the example before that, the VisualTransition is applied when the control goes into the Pressed state. VisualTransitionが適用されるタイミングを制限するにToFrom 、プロパティとプロパティを設定します。You restrict when a VisualTransition is applied by setting the To and From properties. 次の表では、制限が最も厳しいレベルから最も緩いレベルまでを一覧にして示しています。The following table describes the levels of restriction from most restrictive to least restrictive.

制限の種類Type of restriction からの値Value of From の値Value of To
指定した状態から別の指定した状態までFrom a specified state to another specified state の名前VisualStateThe name of a VisualState の名前VisualStateThe name of a VisualState
任意の状態から指定された状態までFrom any state to a specified state 未設定Not set の名前VisualStateThe name of a VisualState
指定した状態から任意の状態までFrom a specified state to any state の名前VisualStateThe name of a VisualState 未設定Not set
任意の状態から他の状態へFrom any state to any other state 未設定Not set 未設定Not set

同じ状態を参照VisualTransitionしているVisualStateGroup内に複数のオブジェクトを含めることができますが、これらは、前の表で指定した順序で使用されます。You can have multiple VisualTransition objects in a VisualStateGroup that refer to the same state, but they will be used in the order that the previous table specifies. 次の例では、2つVisualTransitionのオブジェクトがあります。In the following example, there are two VisualTransition objects. PressedコントロールがTo状態からMouseOver状態に遷移すると、とのVisualTransition両方Fromを持つが使用されます。When the control transitions from the Pressed state to the MouseOver state, the VisualTransition that has both From and To set is used. コントロールが Pressed ではない状態から MouseOver 状態に遷移するときには、別の状態を使用します。When the control transitions from a state that is not Pressed to the MouseOver state, the other state is used.

<!--Take one half second to trasition to the MouseOver state.-->
<VisualTransition To="MouseOver" 
                  GeneratedDuration="0:0:0.5" />

<!--Take one hundredth of a second to transition from the
    Pressed state to the MouseOver state.-->
<VisualTransition From="Pressed" To="MouseOver" 
                  GeneratedDuration="0:0:0.01" />

VisualState Transitions VisualTransitionには、のオブジェクトに適用されるVisualStateGroupオブジェクトを含むプロパティがあります。VisualStateGroupThe VisualStateGroup has a Transitions property that contains the VisualTransition objects that apply to the VisualState objects in the VisualStateGroup. 作成者ControlTemplateは自由に好きなVisualTransitionものを含めることができます。As the ControlTemplate author, you are free to include any VisualTransition you want. ただし、プロパティToFromプロパティがに存在VisualStateGroupVisualTransitionない状態名に設定されている場合、は無視されます。However, if the To and From properties are set to state names that are not in the VisualStateGroup, the VisualTransition is ignored.

次の例は、 VisualStateGroupのをCommonStates示しています。The following example shows the VisualStateGroup for the CommonStates. この例ではVisualTransition 、ボタンの次の遷移のそれぞれに対してを定義します。The example defines a VisualTransition for each of the button's following transitions.

  • Pressed 状態への遷移。To the Pressed state.

  • MouseOver 状態への遷移。To the MouseOver state.

  • Pressed 状態から MouseOver 状態への遷移。From the Pressed state to the MouseOver state.

  • MouseOver 状態から Normal 状態への遷移。From the MouseOver state to the Normal state.

<VisualStateGroup x:Name="CommonStates">

  <!--Define the VisualTransitions that
      can be used when the control transitions 
      between VisualStates that are defined in the
      VisualStatGroup.-->
  <VisualStateGroup.Transitions>

    <!--Take one hundredth of a second to 
        transition to the Pressed state.-->
    <VisualTransition To="Pressed" 
                      GeneratedDuration="0:0:0.01" />

    <!--Take one half second to trasition 
        to the MouseOver state.-->
    <VisualTransition To="MouseOver" 
                      GeneratedDuration="0:0:0.5" />

    <!--Take one hundredth of a second to transition from the
        Pressed state to the MouseOver state.-->
    <VisualTransition From="Pressed" To="MouseOver" 
                      GeneratedDuration="0:0:0.01" />

    <!--Take one and a half seconds to transition from the
        MouseOver state to the Normal state. 
        Have the SolidColorBrush, BorderBrush, fade to blue, 
        then to yellow, and then to black in that time.-->
    <VisualTransition From="MouseOver" To="Normal" 
                      GeneratedDuration="0:0:1.5">
      <Storyboard>
        <ColorAnimationUsingKeyFrames
          Storyboard.TargetProperty="Color"
          Storyboard.TargetName="BorderBrush"
          FillBehavior="HoldEnd" >

          <ColorAnimationUsingKeyFrames.KeyFrames>
            <LinearColorKeyFrame Value="Blue" 
              KeyTime="0:0:0.5" />
            <LinearColorKeyFrame Value="Yellow" 
              KeyTime="0:0:1" />
            <LinearColorKeyFrame Value="Black" 
              KeyTime="0:0:1.5" />

          </ColorAnimationUsingKeyFrames.KeyFrames>
        </ColorAnimationUsingKeyFrames>
      </Storyboard>
    </VisualTransition>
  </VisualStateGroup.Transitions>

  <!--The remainder of the VisualStateGroup is the
      same as the previous example.-->

  <VisualState x:Name="Normal" />

  <VisualState x:Name="MouseOver">
    <Storyboard>
      <ColorAnimation 
        Storyboard.TargetName="BorderBrush" 
        Storyboard.TargetProperty="Color" 
        To="Red" />

    </Storyboard>
  </VisualState>

  <VisualState x:Name="Pressed">
    <Storyboard>
      <ColorAnimation 
        Storyboard.TargetName="BorderBrush" 
        Storyboard.TargetProperty="Color" 
        To="Transparent"/>
    </Storyboard>
  </VisualState>

  <!--The Disabled state is omitted for brevity.-->

</VisualStateGroup>

コントロール コントラクトについて理解しその他のコントロールをカスタマイズする方法Customizing Other Controls by Understanding the Control Contract

ControlTemplate使用してビジュアル構造 (オブジェクトを使用FrameworkElement ) を指定し、ビジュアル動作 (オブジェクトを使用VisualState ) を使用するコントロールは、パーツコントロールモデルを使用します。A control that uses a ControlTemplate to specify its visual structure (by using FrameworkElement objects) and visual behavior (by using VisualState objects) uses the parts control model. WPFWPF 4 に含まれるコントロールの多くは、このモデルを採用しています。Many of the controls that are included with WPFWPF 4 use this model. ControlTemplate作成者が認識する必要があるパーツは、コントロールコントラクトを通じて伝達されます。The parts that a ControlTemplate author needs to be aware of are communicated through the control contract. コントロール コントラクトのパーツについて理解すると、パーツ コントロール モデルを採用するあらゆるコントロールの外観をカスタマイズできます。When you understand the parts of a control contract, you can customize the appearance of any control that uses the parts control model.

コントロール コントラクトには、次の 3 つの要素があります。A control contract has three elements:

  • コントロールのロジックが使用する視覚的要素。The visual elements that the control's logic uses.

  • コントロールの状態および各状態が所属するグループ。The states of the control and the group each state belongs to.

  • コントロールに対して視覚的に作用するパブリック プロパティ。The public properties that visually affect the control.

コントロール コントラクトの視覚的要素Visual Elements in the Control Contract

コントロールのロジックが、 FrameworkElement ControlTemplateにあると対話することがあります。Sometimes a control's logic interacts with a FrameworkElement that is in the ControlTemplate. たとえば、コントロールがその要素のイベントを処理する場合などです。For example, the control might handle an event of one of its elements. コントロールFrameworkElement ControlTemplateで特定のを検索する場合は、その情報を作成者に伝える必要があります。 ControlTemplateWhen a control expects to find a particular FrameworkElement in the ControlTemplate, it must convey that information to the ControlTemplate author. コントロールは、 TemplatePartAttributeを使用して、想定される要素の型と、要素の名前を伝達します。The control uses the TemplatePartAttribute to convey the type of element that is expected, and what the name of the element should be. ButtonコントロールコントラクトにFrameworkElementはパーツがありませんが、などの他のComboBoxコントロールは、を実行します。The Button does not have FrameworkElement parts in its control contract, but other controls, such as the ComboBox, do.

次の例は、 TemplatePartAttribute ComboBoxクラスで指定されたオブジェクトを示しています。The following example shows the TemplatePartAttribute objects that are specified on the ComboBox class. ComboBoxのロジックでは、 PART_Popup Popup内のTextBox というPART_EditableTextBox名前のとを検索する必要があります。ControlTemplateThe logic of ComboBox expects to find a TextBox named PART_EditableTextBox and a Popup named PART_Popup in its ControlTemplate.

[TemplatePartAttribute(Name = "PART_EditableTextBox", Type = typeof(TextBox))]
[TemplatePartAttribute(Name = "PART_Popup", Type = typeof(Popup))]
public class ComboBox : ItemsControl
{
}
<TemplatePartAttribute(Name:="PART_EditableTextBox", Type:=GetType(TextBox))> _
<TemplatePartAttribute(Name:="Part_Popup", Type:=GetType(Popup))> _
Public Class ComboBox
    Inherits ItemsControl

End Class

ControlTemplateの例は、 ComboBox ComboBoxクラスのTemplatePartAttributeオブジェクトによって指定された要素を含むの簡略化されたを示しています。The following example shows a simplified ControlTemplate for the ComboBox that includes the elements that are specified by the TemplatePartAttribute objects on the ComboBox class.

<ControlTemplate TargetType="ComboBox">
  <Grid>
    <ToggleButton x:Name="DropDownToggle"
      HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  
      Margin="-1" HorizontalContentAlignment="Right"
      IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,
                  RelativeSource={RelativeSource TemplatedParent}}">
      <Path x:Name="BtnArrow" Height="4" Width="8" 
        Stretch="Uniform" Margin="0,0,6,0"  Fill="Black"
        Data="F1 M 300,-190L 310,-190L 305,-183L 301,-190 Z " />
    </ToggleButton>
    <ContentPresenter x:Name="ContentPresenter" Margin="6,2,25,2"
      Content="{TemplateBinding SelectionBoxItem}"
      ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
      ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}">
    </ContentPresenter>
    <TextBox x:Name="PART_EditableTextBox"
      Style="{x:Null}"
      Focusable="False"
      Background="{TemplateBinding Background}"
      HorizontalAlignment="Left" 
      VerticalAlignment="Center" 
      Margin="3,3,23,3"
      Visibility="Hidden"
      IsReadOnly="{TemplateBinding IsReadOnly}"/>

    <Popup x:Name="PART_Popup"
      IsOpen="{TemplateBinding IsDropDownOpen}">
      <Border x:Name="PopupBorder" 
        HorizontalAlignment="Stretch" Height="Auto" 
        MinWidth="{TemplateBinding ActualWidth}"
        MaxHeight="{TemplateBinding MaxDropDownHeight}"
        BorderThickness="{TemplateBinding BorderThickness}" 
        BorderBrush="Black" Background="White" CornerRadius="3">
        <ScrollViewer x:Name="ScrollViewer" BorderThickness="0" Padding="1">
          <ItemsPresenter/>
        </ScrollViewer>
      </Border>
    </Popup>

  </Grid>
</ControlTemplate>

コントロール コントラクトの状態States in the Control Contract

コントロールの状態もコントロール コントラクトの一部です。The states of a control are also a part of the control contract. ControlTemplate Buttonのを作成する例は、の状態に応じての外観を指定する方法を示しています。ButtonThe example of creating a ControlTemplate for a Button shows how to specify the appearance of a Button depending on its states. このトピックのVisualState状態に応じてコントロールの外観を変更する」でVisualStateGroup説明されているように、指定した各状態に対してを作成し、を共有GroupNameするすべてVisualStateのオブジェクトをに格納します。You create a VisualState for each specified state and put all VisualState objects that share a GroupName in a VisualStateGroup, as described in Changing the Appearance of a Control Depending on Its State earlier in this topic. サードパーティ製のコントロールでは、 TemplateVisualStateAttributeを使用して状態を指定する必要があります。これにより、Expression Blend などのデザイナーツールで、コントロールテンプレートの作成用のコントロールの状態を公開できます。Third-party controls should specify states by using the TemplateVisualStateAttribute, which enables designer tools, such as Expression Blend, to expose the control's states for authoring control templates.

WPFWPF に付属するコントロールのコントロール コントラクトについては、「コントロールのスタイルとテンプレート」を参照してください。To find the control contract for controls that are included with WPFWPF, see Control Styles and Templates.

コントロール コントラクトのプロパティProperties in the Control Contract

コントロールに視覚的な影響を与えるパブリック プロパティも、コントロール コントラクトに含まれています。The public properties that visually affect the control are also included in the control contract. 新しいControlTemplateを作成せずに、コントロールの外観を変更するには、これらのプロパティを設定します。You can set these properties to change the appearance of the control without creating a new ControlTemplate. また、 TemplateBindingマークアップ拡張機能を使用して、に含まControlTemplateれる要素のプロパティを、 Buttonで定義されているパブリックプロパティにバインドすることもできます。You can also use the TemplateBinding markup extension to bind properties of elements that are in the ControlTemplate to public properties that are defined by the Button.

次の例では、ボタンのコントロール コントラクトを示します。The following example shows the control contract for the button.

[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
[TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Pressed", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates")]
[TemplateVisualState(Name = "Focused", GroupName = "FocusStates")]
public class Button : ButtonBase
{
    public static readonly DependencyProperty BackgroundProperty;
    public static readonly DependencyProperty BorderBrushProperty;
    public static readonly DependencyProperty BorderThicknessProperty;
    public static readonly DependencyProperty ContentProperty;
    public static readonly DependencyProperty ContentTemplateProperty;
    public static readonly DependencyProperty FontFamilyProperty;
    public static readonly DependencyProperty FontSizeProperty;
    public static readonly DependencyProperty FontStretchProperty;
    public static readonly DependencyProperty FontStyleProperty;
    public static readonly DependencyProperty FontWeightProperty;
    public static readonly DependencyProperty ForegroundProperty;
    public static readonly DependencyProperty HorizontalContentAlignmentProperty;
    public static readonly DependencyProperty PaddingProperty;
    public static readonly DependencyProperty TextAlignmentProperty;
    public static readonly DependencyProperty TextDecorationsProperty;
    public static readonly DependencyProperty TextWrappingProperty;
    public static readonly DependencyProperty VerticalContentAlignmentProperty;

    public Brush Background { get; set; }
    public Brush BorderBrush { get; set; }
    public Thickness BorderThickness { get; set; }
    public object Content { get; set; }
    public DataTemplate ContentTemplate { get; set; }
    public FontFamily FontFamily { get; set; }
    public double FontSize { get; set; }
    public FontStretch FontStretch { get; set; }
    public FontStyle FontStyle { get; set; }
    public FontWeight FontWeight { get; set; }
    public Brush Foreground { get; set; }
    public HorizontalAlignment HorizontalContentAlignment { get; set; }
    public Thickness Padding { get; set; }
    public TextAlignment TextAlignment { get; set; }
    public TextDecorationCollection TextDecorations { get; set; }
    public TextWrapping TextWrapping { get; set; }
    public VerticalAlignment VerticalContentAlignment { get; set; }
}
<TemplateVisualState(Name:="Normal", GroupName:="CommonStates")> _
<TemplateVisualState(Name:="MouseOver", GroupName:="CommonStates")> _
<TemplateVisualState(Name:="Pressed", GroupName:="CommonStates")> _
<TemplateVisualState(Name:="Disabled", GroupName:="CommonStates")> _
<TemplateVisualState(Name:="Unfocused", GroupName:="FocusStates")> _
<TemplateVisualState(Name:="Focused", GroupName:="FocusStates")> _
Public Class Button
    Inherits ButtonBase

    Public Shared ReadOnly BackgroundProperty As DependencyProperty
    Public Shared ReadOnly BorderBrushProperty As DependencyProperty
    Public Shared ReadOnly BorderThicknessProperty As DependencyProperty
    Public Shared ReadOnly ContentProperty As DependencyProperty
    Public Shared ReadOnly ContentTemplateProperty As DependencyProperty
    Public Shared ReadOnly FontFamilyProperty As DependencyProperty
    Public Shared ReadOnly FontSizeProperty As DependencyProperty
    Public Shared ReadOnly FontStretchProperty As DependencyProperty
    Public Shared ReadOnly FontStyleProperty As DependencyProperty
    Public Shared ReadOnly FontWeightProperty As DependencyProperty
    Public Shared ReadOnly ForegroundProperty As DependencyProperty
    Public Shared ReadOnly HorizontalContentAlignmentProperty As DependencyProperty
    Public Shared ReadOnly PaddingProperty As DependencyProperty
    Public Shared ReadOnly TextAlignmentProperty As DependencyProperty
    Public Shared ReadOnly TextDecorationsProperty As DependencyProperty
    Public Shared ReadOnly TextWrappingProperty As DependencyProperty
    Public Shared ReadOnly VerticalContentAlignmentProperty As DependencyProperty

    Public Background As Brush
    Public BorderBrush As Brush
    Public BorderThickness As Thickness
    Public Content As Object
    Public ContentTemplate As DataTemplate
    Public FontFamily As FontFamily
    Public FontSize As Double
    Public FontStretch As FontStretch
    Public FontStyle As FontStyle
    Public FontWeight As FontWeight
    Public Foreground As Brush
    Public HorizontalContentAlignment As HorizontalAlignment
    Public Padding As Thickness
    Public TextAlignment As TextAlignment
    Public TextDecorations As TextDecorationCollection
    Public TextWrapping As TextWrapping
    Public VerticalContentAlignment As VerticalAlignment
End Class

を作成ControlTemplateするときは、多くの場合、既存ControlTemplateのを使用して変更を加えるのが最も簡単です。When creating a ControlTemplate, it is often easiest to begin with an existing ControlTemplate and make changes to it. 既存ControlTemplateのを変更するには、次のいずれかの操作を行います。You can do one of the following to change an existing ControlTemplate:

コード例全体Complete Example

このトピックで説明する完全ButtonControlTemplate例を次に示します。The following example shows the complete ButtonControlTemplate that is discussed in this topic.

<StackPanel>
  <StackPanel.Resources>
    <Style TargetType="Button" x:Key="newTemplate">
      <!--Set the Background, Foreground, FontSize, Width, 
                  Height, Margin, and Template properties for
                  the Button.-->
      <Setter Property="Background" Value="Navy"/>
      <Setter Property="Foreground" Value="White"/>
      <Setter Property="FontSize" Value="14"/>
      <Setter Property="Width" Value="100"/>
      <Setter Property="Height" Value="40"/>
      <Setter Property="Margin" Value="10"/>
      <Setter Property="HorizontalContentAlignment" Value="Center"/>
      <Setter Property="VerticalContentAlignment" Value="Center"/>
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="Button">
            <Border x:Name="RootElement">
              <VisualStateManager.VisualStateGroups>

                <!--Define the states and transitions for the common states.
                    The states in the VisualStateGroup are mutually exclusive to
                    each other.-->
                <VisualStateGroup Name="CommonStates">

                  <!--Define the VisualTransitions that can be used when the control
                      transitions between VisualStates that are defined in the
                      VisualStatGroup.-->
                  <VisualStateGroup.Transitions>

                    <!--Take one hundredth of a second to transition to the
                        Pressed state.-->
                    <VisualTransition To="Pressed" 
                                      GeneratedDuration="0:0:0.01" />

                    <!--Take one half second to trasition to the MouseOver state.-->
                    <VisualTransition To="MouseOver" 
                                      GeneratedDuration="0:0:0.5" />

                    <!--Take one hundredth of a second to transition from the
                        Pressed state to the MouseOver state.-->
                    <VisualTransition From="Pressed" To="MouseOver" 
                                      GeneratedDuration="0:0:0.01" />

                    <!--Take one and a half seconds to transition from the
                        MouseOver state to the Normal state. 
                        Have the SolidColorBrush, BorderBrush, fade to blue, 
                        then to yellow, and then to black in that time.-->
                    <VisualTransition From="MouseOver" To="Normal" 
                                          GeneratedDuration="0:0:1.5">
                      <Storyboard>
                        <ColorAnimationUsingKeyFrames
                          Storyboard.TargetProperty="Color"
                          Storyboard.TargetName="BorderBrush"
                          FillBehavior="HoldEnd" >

                          <ColorAnimationUsingKeyFrames.KeyFrames>

                            <LinearColorKeyFrame Value="Blue" 
                              KeyTime="0:0:0.5" />
                            <LinearColorKeyFrame Value="Yellow" 
                              KeyTime="0:0:1" />
                            <LinearColorKeyFrame Value="Black" 
                              KeyTime="0:0:1.5" />

                          </ColorAnimationUsingKeyFrames.KeyFrames>
                        </ColorAnimationUsingKeyFrames>
                      </Storyboard>
                    </VisualTransition>
                  </VisualStateGroup.Transitions>

                  <!--The Normal state is the state the button is in
                      when it is not in another state from this VisualStateGroup.
                      There is no special visual behavior for this state, but
                      the VisualState must be defined in order for the button
                      to return to its initial state.-->
                  <VisualState x:Name="Normal" />

                  <!--Change the border of the button to red when the
                      mouse is over the button.-->
                  <VisualState x:Name="MouseOver">
                    <Storyboard>
                      <ColorAnimation Storyboard.TargetName="BorderBrush"     
                                      Storyboard.TargetProperty="Color"
                                      To="Red" />

                    </Storyboard>
                  </VisualState>

                  <!--Change the border of the button to Transparent when the
                      button is pressed.-->
                  <VisualState x:Name="Pressed">
                    <Storyboard >
                      <ColorAnimation Storyboard.TargetName="BorderBrush" 
                                      Storyboard.TargetProperty="Color" 
                                      To="Transparent" 
                                      />
                    </Storyboard>
                  </VisualState>

                  <!--Show the DisabledRect when the IsEnabled property on
                      the button is false.-->
                  <VisualState x:Name="Disabled">
                    <Storyboard>
                      <DoubleAnimation Storyboard.TargetName="DisabledRect" 
                                       Storyboard.TargetProperty="Opacity"
                                       To="1" Duration="0" />
                    </Storyboard>
                  </VisualState>
                </VisualStateGroup>

                <!--Define the states and transitions for the focus states.
                    The states in the VisualStateGroup are mutually exclusive to
                    each other.-->
                <VisualStateGroup x:Name="FocusStates">

                  <!--Define the VisualStates in this VistualStateGroup.-->
                  <VisualState x:Name="Focused">
                    <Storyboard>
                      <ObjectAnimationUsingKeyFrames 
                        Storyboard.TargetName="FocusVisual" 
                        Storyboard.TargetProperty="Visibility" Duration
                        ="0">
                        
                        <DiscreteObjectKeyFrame KeyTime="0">
                          <DiscreteObjectKeyFrame.Value>
                            <Visibility>Visible</Visibility>
                          </DiscreteObjectKeyFrame.Value>
                        </DiscreteObjectKeyFrame>
                      </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                  </VisualState>
                  <VisualState x:Name="Unfocused">
                    <Storyboard>
                      <ObjectAnimationUsingKeyFrames 
                        Storyboard.TargetName="FocusVisual" 
                        Storyboard.TargetProperty="Visibility"
                        Duration="0">
                        
                        <DiscreteObjectKeyFrame KeyTime="0">
                          <DiscreteObjectKeyFrame.Value>
                            <Visibility>Collapsed</Visibility>
                          </DiscreteObjectKeyFrame.Value>
                        </DiscreteObjectKeyFrame>
                      </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                  </VisualState>
                </VisualStateGroup>
              </VisualStateManager.VisualStateGroups>

              <!--Create the SolidColorBrush for the Background 
                  as an object elemment and give it a name so 
                  it can be referred to elsewhere in the control template.-->
              <Border.Background>
                <SolidColorBrush x:Name="BorderBrush" Color="Black"/>
              </Border.Background>

              <!--Create a border that has a different color by adding smaller grid.
                  The background of this grid is specified by the button's Background
                  property.-->
              <Grid Background="{TemplateBinding Background}" Margin="4">

                <!--Create a Rectangle that indicates that the
                    Button has focus.-->
                <Rectangle Name="FocusVisual" 
                           Visibility="Collapsed" Margin="2" 
                           Stroke="{TemplateBinding Foreground}" 
                           StrokeThickness="1" 
                           StrokeDashArray="1.5 1.5"/>

                <!--Use a ContentPresenter to display the Content of
                    the Button.-->
                <ContentPresenter
                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                  Margin="4,5,4,4" />

                <!--Create a rectangle that causes the button to appear
                    grayed out when it is disabled.-->
                <Rectangle x:Name="DisabledRect" 
                         Fill="#A5FFFFFF"
                         Opacity="0" IsHitTestVisible="false" />
              </Grid>
            </Border>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

  </StackPanel.Resources>

  <Button Style="{StaticResource newTemplate}" 
          Content="Button1"/>

  <Button Style="{StaticResource newTemplate}"
          Background="Purple" 
          Content="Button2" />
</StackPanel>

関連項目See also