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

AControlTemplate視覚的な構造とコントロールの視覚的な動作を指定します。A ControlTemplate specifies the visual structure and visual behavior of a control. コントロールの外観をカスタマイズするには、新しい it 提供することにより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、単純な作成方法を示しますControlTemplateButton外観をカスタマイズできるように、コントロールのコントロール コントラクトを理解する方法について説明します。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クラスを除く、 UserControlThe 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

コントロールが、多くのプロパティをなどあるBackgroundForeground、および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上に斜体、CheckBoxします。For 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選択インジケーター上に配置する チェック ボックスのコンテンツをしながらすることを示すために、X、CheckBoxが選択されています。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. これらの変更を指定する、ControlTemplateCheckBoxします。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選択インジケーター上に X が表示されますと、CheckBoxが選択されています。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

ControlTemplateCheckBoxこのサンプルでは、比較的複雑なため、このトピックで作成する簡単な例を使用して、ControlTemplateButtonします。The 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、結合するFrameworkElement1 つのコントロールを構築するオブジェクト。When you create a ControlTemplate, you combine FrameworkElement objects to build a single control. AControlTemplateが 1 つだけ必要FrameworkElementのルート要素として。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.

次の例では、カスタムControlTemplateButtonします。The following example creates a custom ControlTemplate for the Button. ControlTemplateの視覚的な構造を作成し、Buttonします。The 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>

この例で、GridがそのPanel.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.Backgroundが内の要素のプロパティにバインドされたテンプレートは、ControlTemplateで、設定、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のプロパティ、Buttonにテンプレートがバインド、FrameworkElement.HorizontalAlignmentのプロパティ、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、がControl.HorizontalContentAlignmentにバインドできるFrameworkElement.HorizontalAlignmentします。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. ControlTemplateで、次の方法のいずれかのプロパティを使用する必要があります。The 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.

また場合、ContentPresenterでは、ControlTemplateContentControlContentPresenterに自動的にバインドされます、ContentTemplateContentプロパティ。Also, if the ContentPresenter is in the ControlTemplate of a ContentControl, the ContentPresenter will automatically bind to the ContentTemplate and Content properties. 同様に、ItemsPresenter内にある、ControlTemplateItemsControlに自動的にバインドは、ItemsItemsPresenterプロパティ。Likewise, an ItemsPresenter that is in the ControlTemplate of an ItemsControl will automatically bind to the Items and ItemsPresenter properties.

次の例を使用する 2 つのボタンの作成、ControlTemplate前の例で定義されています。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. 場合でも、ForegroundFontSizeプロパティがテンプレート バインディングされて、その値が継承されるため、それらの設定には効果があります。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 つのボタンの 1 つの blue と紫色です。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. AVisualStateが含まれています、Storyboard含まれている要素の外観を変更する、ControlTemplateします。A 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. Storyboardの色を変更することで、ボタンの境界線の色を変更、BorderBrushします。The Storyboard changes the button's border color by changing the color of the BorderBrush. 参照する場合、ControlTemplate例をこのトピックの先頭には、前述のとおりですBorderBrushの名前を指定します、SolidColorBrushに割り当てられた、BackgroundBorderします。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.
無効Disabled CommonStatesCommonStates コントロールが無効になっています。The control is disabled.
フォーカスされているFocused FocusStatesFocusStates コントロールにフォーカスがあります。The control has focus.
フォーカスされていないUnfocused FocusStatesFocusStates コントロールにフォーカスがありません。The control does not have focus.

Button 2 つの状態グループを定義します。、CommonStatesグループが含まれています、 NormalMouseOverPressed、および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マウス ポインターがない場合でも、そのため、フォーカスを持つことができます、Buttonで、Focused状態、 MouseOverPressed、または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. 追加するVisualStateGroupオブジェクトをVisualStateGroups添付プロパティ。You add VisualStateGroup objects to the VisualStateGroups attached property. 次の例では、定義、VisualStateオブジェクトに対する、 NormalMouseOver、およびPressedはすべての状態、CommonStatesグループ。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添付プロパティをルートFrameworkElementControlTemplateします。Be 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.

1 つの状態から別のコントロールを追加することでスムーズに移行するために発生するアニメーションが必要な時間の量を指定する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次の 1 つ以上を指定します。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

A 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からコントロールになったときに適用、MouseOver状態、Normal状態を前に、の例で、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状態、 MouseOver 、状態、VisualTransition両方を持つFromToセットが使用されます。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" />

VisualStateGroupが、Transitionsプロパティを含む、VisualTransitionオブジェクトに適用される、VisualState内のオブジェクト、VisualStateGroupします。The 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.

次の例は、VisualStateGroupCommonStatesします。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、その情報を伝える必要があります、ControlTemplate作成者です。When 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. ButtonFrameworkElementなど、コントロール コントラクトが、他のコントロールのパーツ、 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が期待する、TextBoxという名前のPART_EditableTextBoxPopupという名前PART_PopupでそのControlTemplateします。The 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

次の例は、簡略化されたControlTemplateComboBoxで指定されている要素を含む、TemplatePartAttributeでオブジェクトをComboBoxクラス。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. 作成する例をControlTemplateButtonの外観を指定する方法を示しています、Button状態に応じて。The example of creating a ControlTemplate for a Button shows how to specify the appearance of a Button depending on its states. 作成する、VisualState各状態を指定し、すべてのVisualStateオブジェクトをその共有をGroupNameで、 VisualStateGroup」の説明に従って、状態に応じたコントロールの外観を変更するこの以前トピックです。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