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);
    }

}
<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 值的VisualState、由 所識別 control 控制項的控制項範本中的某處 x:Name ,或作為您應用程式的資源。 如果沒有,您不會收到例外狀況,但傳回值會是 false 。 所命名 stateName 的狀態可以位於指定控制項之範本中的任何VisualStateGroup元素中。 您必須追蹤哪些狀態位於哪個 VisualStateGroup 狀態,並知道當您從該群組指定新狀態時,會卸載哪些狀態。

一般而言,使用 時,未針對該控制項實例明確定義使用 GoToState 時,包含名稱所參考之視覺狀態的ControlTemplate。 相反地,視覺狀態來自預設控制項樣式,載入為該控制項所有實例的隱含樣式。 如需隱含樣式概念的詳細資訊,請參閱 XAML 控制項範本

VisualStateManager 支援兩個重要功能,適用于控制項作者,以及將自訂範本套用至控制項的應用程式開發人員:

  • 控制項作者或應用程式開發人員使用附加屬性,將 VisualStateManager.VisualStateGroupsVisualStateGroup物件元素新增至 XAML 中控制項範本定義的根項目。 在 VisualStateGroup 元素內,每個 VisualState 都代表控制項的離散視覺狀態。 每個 VisualState 都有代表使用者可變更之 UI 狀態的名稱,或由控制項邏輯變更。 VisualState主要包含分鏡腳本。 這會 Storyboard 以控制項處於該視覺狀態時套用的個別相依性屬性值為目標。
  • 呼叫 VisualStateManager 的靜態 GoToState方法,控制作者或應用程式開發人員在這些狀態之間轉換。 每當控制項邏輯處理指出狀態變更的事件,或控制項邏輯自行起始狀態變更時,控制項作者就會這麼做。 控制項定義程式碼會比較常見,而不是應用程式程式碼,因此應用程式程式碼預設會有所有可能的視覺狀態及其轉換和觸發條件。 或者,它是變更視覺狀態的應用程式程式碼,用來管理應用層級檢視狀態,以回應使用者導向變更主應用程式視窗的大小或方向。

當您呼叫 GoToState 來變更控制項的視覺狀態時, VisualStateManager 會執行下列動作:

  • 首先,它會判斷符合的狀態 stateName 是否存在。 如果沒有,則不會發生任何事,而且方法會傳 false 回 。
  • 如果由 命名 stateNameVisualState存在,而且有分鏡腳本,腳本就會開始。
  • 如果在新要求的狀態之前,控制項使用來自該相同VisualStateGroupVisualState,該分鏡腳本就會停止。 除了新 VisualState 套用動畫的特定屬性之外,控制項會還原為控制項範本及其組合中最初載入的狀態。

如果控制項已在要求為stateNameVisualState 中GoToState 則會傳回 true ,但不會 (腳本不會重新開機) 。

常見的控制項實作模式是定義控制項類別的單一私用方法,以處理控制項的所有可能 VisualState 變更。 要使用的視覺狀態是藉由檢查控制項的屬性來決定。 這些屬性可能是公用或私用。 屬性的值會由控制項邏輯中的處理常式調整,例如 OnGotFocus,並在設定視覺狀態之前立即檢查 Just-In-Time。 本主題中的程式碼範例會使用此實作模式。 或者,您可以從事件處理常式內呼叫個別狀態的 GoToState、從控制事件處理常式覆寫 (OnEvent 方法) ,或從所有可能變更狀態的協助程式方法呼叫, (使用者驅動事件、自動化事件、初始化邏輯) 呼叫。

您也可以從 PropertyChangedCallback 實作內呼叫 GoToState,以取得自訂相依性屬性。

視覺狀態和轉換

除了視覺狀態之外,視覺狀態模型也包含轉換。 轉換是由 腳本 所控制的動畫動作,這些動作會在變更狀態時在每個視覺狀態之間發生。 您可以針對控制項的一組視覺狀態所定義的開始狀態和結束狀態組合,以不同的方式定義轉換。 轉換是由VisualStateGroupTransitions屬性所定義,而且通常會在 XAML 中定義。 大部分的預設控制項範本不會定義轉換,在此情況下,狀態之間的轉換會立即發生。 如需詳細資訊,請參閱 VisualTransition

您也可以定義 VisualTransition ,使其產生隱含轉換。 在 的 FromTo 視覺狀態 VisualTransition 中特別針對動畫設定目標的任何相依性屬性,而且在狀態變更之間具有不同值,都可以使用隱含轉換動畫來產生動畫效果。 這個產生的動畫會使用插補, 在 From 狀態值與這類屬性的 To 狀態值之間轉換。 隱含轉換動畫會持續于 的 GeneratedDurationVisualTransition 所指出的時間。 隱含轉換僅適用于Double、ColorPoint值的屬性。 換句話說,屬性必須使用DoubleAnimation、PointAnimationColorAnimation隱含建立動畫效果。 如需詳細資訊,請參閱 GeneratedDuration

視覺狀態變更的事件

當控制項開始轉換呼叫所要求的 GoToState 狀態時,CurrentStateChanging就會引發。 如果 VisualTransition 套用至狀態變更,此事件會在轉換開始時發生。

當控制項處於呼叫要求 GoToState 的狀態之後,CurrentStateChanged就會引發,就像新的Storyboard開始一樣。 新分鏡腳本完成時不會引發任何事件。

如果未套用VisualTransition則 CurrentStateChanging 和 CurrentStateChanged會連續引發,但如果兩者都發生,則會以該順序保證。

不過,如果狀態變更轉換因新 GoToState 呼叫而中斷,則不會針對第一個狀態轉換引發 CurrentStateChanged 事件。 下一個要求的狀態變更會引發新的事件系列。

OnApplyTemplate 不會針對視覺狀態變更叫用。 OnApplyTemplate 只會針對控制項的初始載入 XAML UI 叫用。

設定自訂控制項的具名視覺狀態

如果您要定義在其控制項範本 XAML 中具有視覺狀態的自訂控制項,最佳作法是將控制項類別屬性設定為可控制取用者的視覺狀態。 若要這樣做,請在控制項定義程式碼的類別層級套用一或多個 TemplateVisualState 屬性。 每個屬性都應該指定狀態的x:Name 屬性,也就是控制項取用者將傳入 GoToState 使用該視覺狀態的呼叫中的stateName值。 如果VisualState 是 VisualStateGroup的一部分,則也應該在屬性定義中指出。

相關的概念是控制項作者應該使用 TemplatePartAttribute來屬性重要控制群組件的名稱。 如果控制取用者想要在套用範本之後,從範本範圍存取具名元件,這非常有用。 TemplateVisualStateAttributeTemplatePartAttribute 結合的協助定義控制項的控制項合約。

自訂 VisualStateManager

在進階案例中,您可以從 VisualStateManager 衍生並變更預設 GoToState 行為。 衍生類別應該覆寫受保護的 GoToStateCore 方法。 呼叫自訂VisualStateManager的任何實例時 GoToState ,都會使用此核心邏輯。

應用程式檢視狀態的視覺狀態

自訂控制項不一定有視覺狀態。 您可以從新的控制項範本使用視覺狀態,這些範本會套用至您要取代預設範本的任何 控制項 實例,方法是設定 Template 屬性。 若要設定此設定,您必須定義您打算用來做為 或 Application.Resources 中的 Page.ResourcesStyle資源的控制項範本和視覺狀態。 最好從預設範本的複本開始,並只修改範本的某些層面,甚至只修改某些視覺狀態,並讓基本組合保持獨立。 如需詳細資訊,請參閱 XAML 控制項範本

視覺狀態可用來變更 頁面內頁面 的屬性或控制項,以考慮應用程式視窗方向。 您的組合或控制項的版面配置相關屬性值可能會根據整體方向是直向或橫向而變更。 如需 此案例 GoToState 的詳細資訊,請參閱 使用 XAML 回應式版面配置

非控制項之元素的視覺狀態

視覺狀態有時適用于您想要變更某些 UI 區域狀態的案例,而該區域不是 控制項 子類別。 您無法直接這麼做,因為 方法的 GoToState控制項參數需要 Control 子類別,這是指VisualStateManager所處理的物件。 頁面Control 子類別,而且您很少會在沒有 的上下文中 Page 顯示 UI,或者 您的 Window.Content 根目錄不是 Control 子類別。 建議您將自訂 UserControlWindow.Content 定義為根目錄,或是您想要套用狀態的其他內容的容器,以 (例如 Panel) 。 然後,不論內容的其餘部分是否為 Control ,您都可以呼叫 GoToStateUserControl 並套用狀態。 例如,您可以將視覺狀態套用至 UI,否則只包含 SwapChainPanel ,只要您將它放在 內 UserControl ,且宣告的具名狀態會套用至範本的父 UserControl 系或具名 SwapChainPanel 部分的屬性即可。

適用於

另請參閱