VisualStateManager.GoToState(Control, String, Boolean) メソッド

定義

名前で新しい VisualState を要求して、2 つの状態間でコントロールを切り替えます。

public:
 static bool GoToState(Control ^ control, Platform::String ^ stateName, bool useTransitions);
 static bool GoToState(Control const& control, winrt::hstring const& stateName, bool const& useTransitions);
public static bool GoToState(Control control, string stateName, bool useTransitions);
function goToState(control, stateName, useTransitions)
Public Shared Function GoToState (control As Control, stateName As String, useTransitions As Boolean) As Boolean

パラメーター

control
Control

状態を遷移するコントロール。

stateName
String

Platform::String

winrt::hstring

切り替え先の状態。

useTransitions
Boolean

bool

状態 間の遷移に VisualTransition を 使用する場合は true。 false を指定 すると、切り替えの使用をスキップし、要求された状態に直接移動します。 既定値は false です。

戻り値

Boolean

bool

コントロールが正常に新しい状態に遷移した場合、または既にその状態を使用していた場合は true。それ以外の場合は false

この例では、GoToState メソッドを使用して状態間を遷移する制御ロジックを示します。

private void UpdateStates(bool useTransitions)
{
    if (Value >= 0)
    {
        VisualStateManager.GoToState(this, "Positive", useTransitions);
    }
    else
    {
        VisualStateManager.GoToState(this, "Negative", useTransitions);
    }

    if (isFocused)
    {
        VisualStateManager.GoToState(this, "Focused", useTransitions);
    }
    else
    {
        VisualStateManager.GoToState(this, "Unfocused", useTransitions);
    }

}
Private Sub UpdateStates(ByVal useTransitions As Boolean)
    If Value >= 0 Then
        VisualStateManager.GoToState(Me, "Positive", useTransitions)
    Else
        VisualStateManager.GoToState(Me, "Negative", useTransitions)
    End If

    If isFocused Then
        VisualStateManager.GoToState(Me, "Focused", useTransitions)
    Else
        VisualStateManager.GoToState(Me, "Unfocused", useTransitions)
    End If

End Sub
<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:NumericUpDownCustomControl"
    >
    <Style TargetType="local:NumericUpDown">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:NumericUpDown">
                    <Grid  Margin="3" 
                Background="{TemplateBinding Background}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="ValueStates">
                                
                                <!--Make the Value property red when it is negative.-->
                                <VisualState x:Name="Negative">
                                    <Storyboard>
                                        <ColorAnimation To="Red"
                                    Storyboard.TargetName="TextBlock" 
                                    Storyboard.TargetProperty="(Foreground).(SolidColorBrush.Color)"/>
                                    </Storyboard>
                                </VisualState>
                                <!--Return the control to its initial state by
                    return the TextBlock Foreground to its 
                    original color.-->
                                <VisualState x:Name="Positive" />
                            </VisualStateGroup>

                            <VisualStateGroup x:Name="FocusStates">
                                <!--Add a focus rectangle to highlight the entire control
                    when it has focus.-->
                                <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>
                                <!--Return the control to its initial state by
                    hiding the focus rectangle.-->
                                <VisualState x:Name="Unfocused"/>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>

                            <Border BorderThickness="1" BorderBrush="Gray" 
                    Margin="7,2,2,2" Grid.RowSpan="2" 
                    Background="#E0FFFFFF"
                    VerticalAlignment="Center" 
                    HorizontalAlignment="Stretch">
                                <TextBlock x:Name="TextBlock" TextAlignment="Center" Padding="5"
                           Foreground="{TemplateBinding Foreground}"/>

                            </Border>

                            <RepeatButton Content="Up" Margin="2,5,5,0" 
                          x:Name="UpButton"
                          Grid.Column="1" Grid.Row="0"
                          Foreground="Green"/>
                            <RepeatButton Content="Down" Margin="2,0,5,5" 
                          x:Name="DownButton"
                          Grid.Column="1" Grid.Row="1" 
                          Foreground="Green"/>

                            <Rectangle Name="FocusVisual" Grid.ColumnSpan="2" Grid.RowSpan="2" 
                       Stroke="Red" StrokeThickness="1"  
                       Visibility="Collapsed"/>
                        </Grid>

                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
</ResourceDictionary>

注釈

このメソッドは、制御ロジックで使用されます。 通常、必要なのは、カスタム コントロールを作成している場合、またはビューステートにアプリ レベルのロジックを使用している場合 (アプリ のウィンドウ サイズや向きの変更のためにアプリ コンテンツを更新するなど)。

このメソッドを呼び出すと、stateName 値に一致する x:Name 値を持つ VisualState が、コントロールによって識別されるコントロールのコントロール テンプレート内のどこか、またはアプリのリソースとして使用されることが想定されます。 存在しない場合、例外は取得されませんが、戻り値は false になります。 stateName で指定された状態は、指定した Control のテンプレート内の VisualStateGroup 要素のいずれかに含めることができます。 どの状態が VisualStateGroup にあるかを追跡し、そのグループから新しい状態を指定したときにアンロードされる状態を把握するのはユーザーの責任です。

通常、GoToState を使用するときに名前によって参照される視覚的な状態を含む ControlTemplate は、そのコントロール インスタンスに対して明示的に定義されていません。 代わりに、表示状態は、そのコントロールのすべてのインスタンスの暗黙的なスタイルとして読み込まれる既定のコントロール スタイルから取得されます。 暗黙的なスタイルの概念の詳細については、「 クイック スタート: コントロール テンプレート」を参照してください。

VisualStateManager では、コントロール作成者と、コントロールにカスタム テンプレートを適用するアプリ開発者向けに、次の 2 つの重要な機能がサポートされています。

  • コントロール作成者またはアプリ開発者は、 VisualStateManager.VisualStateGroups 添付プロパティを使用して、XAML のコントロール テンプレート定義のルート要素に VisualStateGroup オブジェクト要素を追加します。 VisualStateGroup 要素内では、各 VisualState はコントロールの個別のビジュアル状態を表します。 各 VisualState には、ユーザーが変更したり、コントロール ロジックによって変更したりできる UI 状態を表す名前があります。 VisualState は主にストーリーボードで構成されます。 この ストーリーボード は、コントロールがそのビジュアル状態のときに適用する必要がある個々の依存関係プロパティ値を対象とします。
  • VisualStateManager の静的 GoToState メソッドを呼び出して、作成者またはアプリ開発者がこれらの状態間を切り替える制御を行います。 コントロール作成者は、コントロール ロジックが状態の変化を示すイベントを処理するとき、またはコントロール ロジックが単独で状態変更を開始するたびにこれを行います。 コントロール定義コードでは、アプリ コードではなくこれを行う方が一般的です。これにより、アプリ コードに対して考えられるすべての表示状態とその遷移とトリガー条件が既定で存在します。 または、メイン アプリ ウィンドウのサイズまたは向きに対するユーザー主導の変更に応じてアプリ レベルのビュー状態を管理するために、ビジュアル状態を変更しているアプリ コードです。

GoToState を呼び出してコントロールの表示状態を変更すると、 VisualStateManager は次のアクションを実行します。

  • まず、 stateName と一致する状態が存在するかどうかを決定します。 そうでない場合、何も起こらず、メソッドは false を返 します
  • stateName によって名前が付けられた VisualState が存在し、ストーリーボードがある場合は、ストーリーボードが開始されます。
  • 新しく要求された状態より前の同じ VisualStateGroup からコントロールが使用していた VisualState にストーリーボードがある場合、そのストーリーボードは停止します。 新しい VisualState がアニメーションを適用する特定のプロパティを除き、コントロールはコントロール テンプレートとそのコンポジションから最初に読み込まれた状態に戻ります。

コントロールが stateName として要求された VisualState に既にある場合、GoToState は true を返しますが、それ以外の場合はアクションはありません (ストーリーボードは再起動されません)。

一般的なコントロール実装パターンは、コントロールに対して可能なすべての VisualState 変更を処理する、コントロール クラスの 1 つのプライベート メソッドを定義することです。 使用するビジュアル状態は、コントロールのプロパティを確認することによって決定されます。 これらのプロパティは、パブリックまたはプライベートである可能性があります。 プロパティの値は、 OnGotFocus などのイベントのコントロール ロジックのハンドラーによって調整され、ビジュアル状態を設定する直前に Just-In-Time でチェックされます。 このトピックのコード例では、この実装パターンを使用します。 または、イベント ハンドラー内、コントロール イベント ハンドラーのオーバーライド ( OnEvent メソッド)、または状態の変更に対して考えられるすべての推進力 (ユーザー駆動型イベント、オートメーション イベント、初期化ロジック) によって呼び出されるヘルパー メソッドから、個々の状態に対して GoToState を呼び出すこともできます。

カスタム依存関係プロパティの PropertyChangedCallback 実装内から GoToState を呼び出すこともできます。

表示状態と遷移

ビジュアル状態に加えて、ビジュアル状態モデルには遷移も含まれます。 切り替えは、状態が変更されたときに各ビジュアル状態の間で発生する ストーリーボード によって制御されるアニメーション アクションです。 遷移は、コントロールの一連の表示状態によって定義される開始状態と終了状態の組み合わせごとに異なる方法で定義できます。 遷移は VisualStateGroupTransitions プロパティによって定義され、通常は XAML で定義されます。 ほとんどの既定のコントロール テンプレートでは遷移は定義されません。この場合、状態間の遷移は瞬時に行われます。 詳細については、「 VisualTransition」を参照してください。

VisualTransition を定義して、暗黙的な遷移を生成することもできます。 VisualTransitionFrom またはTo ビジュアル状態でアニメーションを特に対象とし、状態変更全体で異なる値を持つ依存関係プロパティは、暗黙的な遷移アニメーションを使用してアニメーション化できます。 この生成されたアニメーションは、補間を使用して、このようなプロパティの From 状態値と To 状態値の間で遷移します。 暗黙的な切り替えアニメーションは、VisualTransitionGeneratedDuration 値によって示された時間に対して持続します。 暗黙的な遷移は、 DoubleColor 、または Point の値であるプロパティにのみ適用されます。 つまり、DoubleAnimation、PointAnimation、または ColorAnimation を使用して、プロパティを暗黙的にアニメーション化できる必要があります。 詳細については、「 GeneratedDuration」を参照してください。

ビジュアル状態の変更に関するイベント

CurrentStateChanging は、GoToState 呼び出しの要求に応じてコントロールが状態の遷移を開始したときに発生します。 状態の変更に VisualTransition が適用されている場合、このイベントは遷移の開始時に発生します。

CurrentStateChanged は、新しい ストーリーボード が開始されるのと同じように、GoToState 呼び出しによって要求された状態のコントロールの後に発生します。 新しいストーリーボードの完了時にイベントは発生しません。

VisualTransition が適用されていない場合、CurrentStateChangingCurrentStateChanged は連続して起動しますが、両方が発生した場合は、その順序で保証されます。

ただし、新しい GoToState 呼び出しによって状態変更の遷移が中断された場合、最初の状態遷移に対して CurrentStateChanged イベントは発生しません。 次に要求された状態変更のために、新しいイベント シリーズが発生します。

OnApplyTemplate は、ビジュアル状態の変更に対して呼び出されません。 OnApplyTemplate は、XAML UI へのコントロールの初期読み込みに対してのみ呼び出されます。

カスタム コントロールの名前付きビジュアル状態の属性付け

コントロール テンプレート XAML でビジュアル状態を持つカスタム コントロールを定義する場合は、使用可能なビジュアル状態をコンシューマーに制御するようにコントロール クラスを属性付けすることをお勧めします。 これを行うには、コントロール定義コードのクラス レベルで 1 つ以上の TemplateVisualState 属性を適用します。 各属性では、状態の x:Name 属性を指定する必要があります。これは、コントロール コンシューマーがそのビジュアル状態を使用するために GoToState 呼び出しで渡す stateName 値です。 VisualState が VisualStateGroup の一部である場合は、属性定義にも指定する必要があります。

関連する概念は、コントロール作成者が TemplatePartAttribute を使用してキー コントロール パーツの名前を属性化する必要があるということです。 これは、コントロール コンシューマーがテンプレートの適用後にテンプレート スコープから名前付きパーツにアクセスする場合に非常に役立ちます。 TemplateVisualStateAttributeTemplatePartAttribute の組み合わせにより、コントロールのコントロール コントラクトが定義されます。

Custom VisualStateManager

高度なシナリオとして、 VisualStateManager から派生し、既定の GoToState 動作を変更できます。 派生クラスは、保護された GoToStateCore メソッドをオーバーライドする 必要があります。 カスタム VisualStateManager のインスタンスは、GoToState メソッドが呼び出されたときにこの Core ロジックを使用します。

アプリビューの状態の表示状態

ビジュアルの状態は、必ずしもカスタム コントロールの場合ではありません。 Template プロパティを設定することで、既定のテンプレートを置き換えるコントロール インスタンスに適用する新しいコントロール テンプレートの表示状態を使用できます。 これを設定するには、 または Application.Resourcesにある Style リソースとして使用する予定のコントロール テンプレートとビジュアル状態を定義するPage.Resources必要があります。 既定のテンプレートのコピーから始めて、テンプレートの特定の側面のみを変更するか、視覚的な状態の一部を変更して基本的な構成をそのままにしておくことをお勧めします。 詳しくは、「クイック スタート: コントロール テンプレート」をご覧ください。

表示状態を使用すると、ページ内の ページ またはコントロールのプロパティを変更して、アプリ ウィンドウの向きを考慮できます。 全体の向きが縦か横かによって、コンポジションまたはコントロールのレイアウト関連のプロパティ値が変わる場合があります。 GoToState のこのシナリオの詳細については、「 クイック スタート: さまざまなウィンドウ サイズのアプリを設計する」を参照してください。

コントロールではない要素の表示状態

ビジュアル状態は、 コントロール サブクラスではない UI の一部の領域の状態を変更するシナリオに役立つことがあります。 GoToState メソッドのコントロール パラメーターには、VisualStateManager が動作するオブジェクトを参照する Control サブクラスが必要であるため、これを直接行うことはできません。 PageControl サブクラスであり、 Page がないコンテキストや Window.Content ルートが Control サブクラスではないコンテキストで UI が表示されることはほとんどありません。 カスタム UserControlWindow.Content ルートとして定義するか、状態を適用する他のコンテンツ ( パネルなど) のコンテナーとして定義することをお勧めします。 その後、 UserControl で GoToState を呼び出し、残りのコンテンツが Control であるかどうかに関係なく状態を適用できます。 たとえば、親 UserControl またはテンプレートの名前付き SwapChainPanel 部分のプロパティに適用される名前付き状態を UserControl 内に配置し、宣言されている限り、SwapChainPanel だけで構成される UI に視覚的な状態を適用できます。

適用対象

こちらもご覧ください