VisualStateManager.GoToState(Control, String, Boolean) 方法
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
藉由依名稱要求新的 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
。
傳回
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.VisualStateGroups
VisualStateGroup物件元素新增至 XAML 中控制項範本定義的根項目。 在VisualStateGroup
元素內,每個 VisualState 都代表控制項的離散視覺狀態。 每個VisualState
都有代表使用者可變更之 UI 狀態的名稱,或由控制項邏輯變更。VisualState
主要包含分鏡腳本。 這會Storyboard
以控制項處於該視覺狀態時套用的個別相依性屬性值為目標。 - 呼叫 VisualStateManager 的靜態 GoToState方法,控制作者或應用程式開發人員在這些狀態之間轉換。 每當控制項邏輯處理指出狀態變更的事件,或控制項邏輯自行起始狀態變更時,控制項作者就會這麼做。 控制項定義程式碼會比較常見,而不是應用程式程式碼,因此應用程式程式碼預設會有所有可能的視覺狀態及其轉換和觸發條件。 或者,它是變更視覺狀態的應用程式程式碼,用來管理應用層級檢視狀態,以回應使用者導向變更主應用程式視窗的大小或方向。
當您呼叫 GoToState
來變更控制項的視覺狀態時, VisualStateManager 會執行下列動作:
- 首先,它會判斷符合的狀態
stateName
是否存在。 如果沒有,則不會發生任何事,而且方法會傳false
回 。 - 如果由 命名
stateName
的VisualState存在,而且有分鏡腳本,腳本就會開始。 - 如果在新要求的狀態之前,控制項使用來自該相同VisualStateGroup的VisualState,該分鏡腳本就會停止。 除了新
VisualState
套用動畫的特定屬性之外,控制項會還原為控制項範本及其組合中最初載入的狀態。
如果控制項已在要求為stateName的VisualState 中, GoToState
則會傳回 true
,但不會 (腳本不會重新開機) 。
常見的控制項實作模式是定義控制項類別的單一私用方法,以處理控制項的所有可能 VisualState 變更。 要使用的視覺狀態是藉由檢查控制項的屬性來決定。 這些屬性可能是公用或私用。 屬性的值會由控制項邏輯中的處理常式調整,例如 OnGotFocus,並在設定視覺狀態之前立即檢查 Just-In-Time。 本主題中的程式碼範例會使用此實作模式。 或者,您可以從事件處理常式內呼叫個別狀態的 GoToState、從控制事件處理常式覆寫 (OnEvent 方法) ,或從所有可能變更狀態的協助程式方法呼叫, (使用者驅動事件、自動化事件、初始化邏輯) 呼叫。
您也可以從 PropertyChangedCallback 實作內呼叫 GoToState,以取得自訂相依性屬性。
視覺狀態和轉換
除了視覺狀態之外,視覺狀態模型也包含轉換。 轉換是由 腳本 所控制的動畫動作,這些動作會在變更狀態時在每個視覺狀態之間發生。 您可以針對控制項的一組視覺狀態所定義的開始狀態和結束狀態組合,以不同的方式定義轉換。 轉換是由VisualStateGroup的Transitions屬性所定義,而且通常會在 XAML 中定義。 大部分的預設控制項範本不會定義轉換,在此情況下,狀態之間的轉換會立即發生。 如需詳細資訊,請參閱 VisualTransition。
您也可以定義 VisualTransition ,使其產生隱含轉換。 在 的 From 或To 視覺狀態 VisualTransition
中特別針對動畫設定目標的任何相依性屬性,而且在狀態變更之間具有不同值,都可以使用隱含轉換動畫來產生動畫效果。 這個產生的動畫會使用插補, 在 From 狀態值與這類屬性的 To 狀態值之間轉換。 隱含轉換動畫會持續于 的 GeneratedDuration 值 VisualTransition
所指出的時間。 隱含轉換僅適用于Double、Color或Point值的屬性。 換句話說,屬性必須使用DoubleAnimation、PointAnimation或ColorAnimation隱含建立動畫效果。 如需詳細資訊,請參閱 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來屬性重要控制群組件的名稱。 如果控制取用者想要在套用範本之後,從範本範圍存取具名元件,這非常有用。 TemplateVisualStateAttribute 和 TemplatePartAttribute 結合的協助定義控制項的控制項合約。
自訂 VisualStateManager
在進階案例中,您可以從 VisualStateManager 衍生並變更預設 GoToState
行為。 衍生類別應該覆寫受保護的 GoToStateCore 方法。 呼叫自訂VisualStateManager的任何實例時 GoToState
,都會使用此核心邏輯。
應用程式檢視狀態的視覺狀態
自訂控制項不一定有視覺狀態。 您可以從新的控制項範本使用視覺狀態,這些範本會套用至您要取代預設範本的任何 控制項 實例,方法是設定 Template 屬性。 若要設定此設定,您必須定義您打算用來做為 或 Application.Resources
中的 Page.Resources
Style資源的控制項範本和視覺狀態。 最好從預設範本的複本開始,並只修改範本的某些層面,甚至只修改某些視覺狀態,並讓基本組合保持獨立。 如需詳細資訊,請參閱 XAML 控制項範本。
視覺狀態可用來變更 頁面內頁面 的屬性或控制項,以考慮應用程式視窗方向。 您的組合或控制項的版面配置相關屬性值可能會根據整體方向是直向或橫向而變更。 如需 此案例 GoToState
的詳細資訊,請參閱 使用 XAML 回應式版面配置。
非控制項之元素的視覺狀態
視覺狀態有時適用于您想要變更某些 UI 區域狀態的案例,而該區域不是 控制項 子類別。 您無法直接這麼做,因為 方法的 GoToState
控制項參數需要 Control
子類別,這是指VisualStateManager所處理的物件。
頁面 是 Control
子類別,而且您很少會在沒有 的上下文中 Page
顯示 UI,或者 您的 Window.Content 根目錄不是 Control
子類別。 建議您將自訂 UserControlWindow.Content
定義為根目錄,或是您想要套用狀態的其他內容的容器,以 (例如 Panel) 。 然後,不論內容的其餘部分是否為 Control
,您都可以呼叫 GoToState
UserControl
並套用狀態。 例如,您可以將視覺狀態套用至 UI,否則只包含 SwapChainPanel ,只要您將它放在 內 UserControl
,且宣告的具名狀態會套用至範本的父 UserControl
系或具名 SwapChainPanel
部分的屬性即可。