다음을 통해 공유


VisualStateManager.GoToState(Control, String, Boolean) 메서드

정의

이름으로 새 VisualState 를 요청하여 두 상태 간에 컨트롤을 전환합니다.

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

true 이면 VisualTransition을 사용하여 상태 간에 전환합니다. 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은 해당 컨트롤 instance 대해 특별히 정의되지 않습니다. 대신 시각적 상태는 해당 컨트롤의 모든 인스턴스에 대한 암시적 스타일로 로드되는 기본 컨트롤 스타일에서 가져옵니다. 암시적 스타일 개념에 대한 자세한 내용은 빠른 시작: 컨트롤 템플릿을 참조하세요.

VisualStateManager 는 컨트롤 작성자와 컨트롤에 사용자 지정 템플릿을 적용하는 앱 개발자를 위한 두 가지 중요한 기능을 지원합니다.

  • 컨트롤 작성자 또는 앱 개발자는 VisualStateManager.VisualStateGroups 연결된 속성을 사용하여 XAML에서 컨트롤 템플릿 정의의 루트 요소에 VisualStateGroup 개체 요소를 추가합니다. VisualStateGroup 요소 내에서 각 VisualState는 컨트롤의 개별 시각적 상태를 나타냅니다. 각 VisualState 에는 사용자가 변경하거나 제어 논리로 변경할 수 있는 UI 상태를 나타내는 이름이 있습니다. VisualState는 주로 Storyboard로 구성됩니다. 이 Storyboard 는 컨트롤이 해당 시각적 상태에 있을 때마다 적용해야 하는 개별 종속성 속성 값을 대상으로 합니다.
  • 컨트롤 작성자 또는 앱 개발자는 VisualStateManager의 정적 GoToState 메서드를 호출하여 이러한 상태 간에 전환합니다. 컨트롤 작성자는 컨트롤 논리가 상태 변경을 나타내는 이벤트를 처리하거나 제어 논리가 자체적인 상태 변경을 시작할 때마다 이 작업을 수행합니다. 앱 코드 대신 컨트롤 정의 코드에서 이 작업을 수행하는 것이 더 일반적이므로 가능한 모든 시각적 상태와 해당 전환 및 트리거 조건이 앱 코드에 대해 기본적으로 존재합니다. 또는 기본 앱 창의 크기 또는 방향에 대한 사용자 기반 변경에 대응하여 앱 수준 보기 상태를 관리하기 위해 시각적 상태를 변경하는 앱 코드입니다.

GoToState를 호출하여 컨트롤의 시각적 상태를 변경하는 경우 VisualStateManager 는 다음 작업을 수행합니다.

  • 먼저 stateName 과 일치하는 상태가 있는지 여부를 결정합니다. 그렇지 않으면 아무 일도 발생하지 않으며 메서드는 false를 반환 합니다.
  • stateName으로 명명된 VisualState가 존재하고 Storyboard가 있는 경우 스토리보드가 시작됩니다.
  • 새로 요청된 상태 이전에 컨트롤이 동일한 VisualStateGroup에서 사용하던 VisualStateStoryboard가 있으면 해당 스토리보드가 중지됩니다. 새 VisualState 가 애니메이션을 적용하는 특정 속성 외에 컨트롤은 컨트롤 템플릿 및 해당 컴퍼지션에서 처음 로드된 상태로 되돌아갑니다.

컨트롤이 stateName으로 요청된 VisualState에 이미 있는 경우 GoToState는 true를 반환하지만, 그렇지 않으면 작업이 없습니다(스토리보드가 다시 시작되지 않음).

일반적인 컨트롤 구현 패턴은 컨트롤에 대해 가능한 모든 VisualState 변경 내용을 처리할 컨트롤 클래스의 단일 프라이빗 메서드를 정의하는 것입니다. 사용할 시각적 상태는 컨트롤의 속성을 확인하여 결정됩니다. 이러한 속성은 퍼블릭 또는 프라이빗일 수 있습니다. 속성 값은 OnGotFocus와 같은 이벤트에 대한 제어 논리의 처리기에 의해 조정되며 시각적 상태를 설정하기 직전에 Just-In-Time으로 확인됩니다. 이 항목의 코드 예제에서는 이 구현 패턴을 사용합니다. 또는 이벤트 처리기 내에서, 제어 이벤트 처리기 재정의( OnEvent 메서드) 또는 상태 변경(사용자 기반 이벤트, 자동화 이벤트, 초기화 논리)에 대해 가능한 모든 추진력으로 호출되는 도우미 메서드에서 개별 상태에 대해 GoToState를 호출할 수 있습니다.

사용자 지정 종속성 속성에 대한 PropertyChangedCallback 구현 내에서 GoToState를 호출할 수도 있습니다.

시각적 상태 및 전환

시각적 상태 외에도 시각적 상태 모델에는 전환도 포함됩니다. 전환은 상태가 변경될 때 각 시각적 상태 간에 발생하는 Storyboard 에 의해 제어되는 애니메이션 작업입니다. 컨트롤의 시각적 상태 집합에 정의된 대로 시작 상태와 종료 상태의 각 조합에 대해 전환이 다르게 정의될 수 있습니다. 전환은 VisualStateGroupTransitions 속성에 의해 정의되며 일반적으로 XAML에 정의됩니다. 대부분의 기본 컨트롤 템플릿은 전환을 정의하지 않으며, 이 경우 상태 간 전환이 즉시 발생합니다. 자세한 내용은 VisualTransition을 참조하세요.

암시적 전환을 생성할 수 있도록 VisualTransition 을 정의할 수도 있습니다. VisualTransitionFrom 또는To 시각적 상태 중 하나에서 애니메이션을 대상으로 하고 상태 변경 간에 값이 다른 종속성 속성은 암시적 전환 애니메이션으로 애니메이션 효과를 적용할 수 있습니다. 이 생성된 애니메이션은 보간을 사용하여 이러한 속성의 From 상태 값과 To 상태 값 간에 전환됩니다. 암시적 전환 애니메이션은 VisualTransitionGeneratedDuration 값에 명시된 시간 동안 지속됩니다. 암시적 전환은 Double, Color 또는 Point 값인 속성에만 적용됩니다. 즉, 속성은 DoubleAnimation, PointAnimation 또는ColorAnimation을 사용하여 암시적으로 애니메이션 효과를 적용할 수 있어야 합니다. 자세한 내용은 GeneratedDuration을 참조하세요.

시각적 상태 변경에 대한 이벤트

CurrentStateChanging 은 컨트롤이 GoToState 호출에서 요청한 대로 상태를 전환하기 시작할 때 발생합니다. VisualTransition이 상태 변경에 적용되는 경우 이 이벤트는 전환이 시작될 때 발생합니다.

CurrentStateChanged 는 새 Storyboard 가 시작되는 것처럼 GoToState 호출에서 요청한 대로 컨트롤이 상태에 있으면 발생합니다. 새 스토리보드 완료 시 이벤트가 발생하지 않습니다.

VisualTransition이 적용되지 않으면 CurrentStateChangingCurrentStateChanged가 연속해서 빠르게 발생하지만 둘 다 발생하는 경우 해당 순서로 보장됩니다.

그러나 새 GoToState 호출로 인해 상태 변경 전환이 중단되는 경우 첫 번째 상태 전환에 대해 CurrentStateChanged 이벤트가 발생하지 않습니다. 다음 요청된 상태 변경에 대해 새 이벤트 계열이 발생합니다.

OnApplyTemplate 은 시각적 상태 변경에 대해 호출되지 않습니다. OnApplyTemplate 은 XAML UI에 대한 컨트롤의 초기 로드에 대해서만 호출됩니다.

사용자 지정 컨트롤의 명명된 시각적 상태 특성 지정

컨트롤 템플릿 XAML에 시각적 상태가 있는 사용자 지정 컨트롤을 정의하는 경우 컨트롤 클래스의 특성을 지정하여 소비자에게 사용할 수 있는 시각적 상태를 제어하도록 지정하는 것이 좋습니다. 이렇게 하려면 컨트롤 정의 코드의 클래스 수준에서 하나 이상의 TemplateVisualState 특성을 적용합니다. 각 특성은 상태의 x:Name 특성을 지정해야 합니다. 이 특성은 컨트롤 소비자가 해당 시각적 상태를 사용하기 위해 GoToState 호출에서 전달하는 stateName 값입니다. VisualStateVisualStateGroup의 일부인 경우 특성 정의에도 표시되어야 합니다.

관련 개념은 컨트롤 작성자가 TemplatePartAttribute를 사용하여 키 컨트롤 파트의 이름을 특성화해야 한다는 것입니다. 이는 컨트롤 소비자가 템플릿이 적용된 후 템플릿 scope 명명된 파트에 액세스하려는 경우에 매우 유용합니다. TemplateVisualStateAttributeTemplatePartAttribute 결합은 컨트롤에 대한 컨트롤 계약을 정의하는 데 도움이 됩니다.

사용자 지정 VisualStateManager

고급 시나리오에서는 VisualStateManager 에서 파생하고 기본 GoToState 동작을 변경할 수 있습니다. 파생 클래스는 보호된 GoToStateCore 메서드를 재정의해야 합니다. 사용자 지정 VisualStateManager의 모든 instance GoToState 메서드가 호출될 때 이 Core 논리를 사용합니다.

앱 보기 상태에 대한 시각적 상태

시각적 상태가 반드시 사용자 지정 컨트롤에 대한 것은 아닙니다. 템플릿 속성을 설정하여 기본 템플릿을 바꾸는 모든 Control instance 적용하는 새 컨트롤 템플릿의 시각적 상태를 사용할 수 있습니다. 이를 설정하려면 또는 Application.Resources에 있는 Style 리소스 Page.Resources 로 사용하려는 컨트롤 템플릿 및 시각적 상태를 정의해야 합니다. 항상 기본 템플릿의 복사본으로 시작하고 템플릿의 특정 측면만 수정하거나 일부 시각적 상태를 수정하고 기본 컴퍼지션만 그대로 두는 것이 가장 좋습니다. 자세한 내용은 빠른 시작: 컨트롤 템플릿을 참조하세요.

시각적 상태를 사용하여 페이지 또는 페이지 내 컨트롤의 속성을 변경하여 앱 창 방향을 설명할 수 있습니다. 전체 방향이 세로인지 가로인지에 따라 컴퍼지션 또는 컨트롤의 레이아웃 관련 속성 값이 변경될 수 있습니다. GoToState에 대한 이 시나리오에 대한 자세한 내용은 빠른 시작: 다양한 창 크기에 대한 앱 디자인을 참조하세요.

컨트롤이 아닌 요소의 시각적 상태

시각적 상태는 Control 하위 클래스가 아닌 일부 UI 영역의 상태를 변경하려는 시나리오에 유용할 수 있습니다. GoToState 메서드의 컨트롤 매개 변수에는 VisualStateManager가 작동하는 개체를 참조하는 Control 하위 클래스가 필요하기 때문에 이 작업을 직접 수행할 수 없습니다. PageControl 하위 클래스이며 Page가 없거나 Window.Content 루트가 Control 하위 클래스가 아닌 컨텍스트에서 UI를 표시하는 경우는 매우 드뭅니다. 사용자 지정 UserControlWindow.Content 루트로 정의하거나 상태를 적용하려는 다른 콘텐츠(예: 패널)의 컨테이너로 정의하는 것이 좋습니다. 그런 다음 UserControl 에서 GoToState를 호출하고 나머지 콘텐츠가 컨트롤인지 여부에 관계없이 상태를 적용할 수 있습니다. 예를 들어 UserControl 내에 배치하고 부모 UserControl의 속성 또는 템플릿의 명명된 SwapChainPanel 부분에 적용되는 명명된 상태를 선언하는 한, 그렇지 않으면 SwapChainPanel로 구성된 시각적 상태를 UI에 적용할 수 있습니다.

적용 대상

추가 정보