VisualStateManager 類別

定義

管理視覺狀態,以及控制項視覺狀態之間轉換的邏輯。 也提供 VisualStateManager.VisualStateGroups 的附加屬性支援,這是您在 XAML 中為控制項範本定義視覺狀態的方式。

/// [Windows.Foundation.Metadata.ContractVersion(Windows.Foundation.UniversalApiContract, 65536)]
/// [Windows.Foundation.Metadata.MarshalingBehavior(Windows.Foundation.Metadata.MarshalingType.Agile)]
/// [Windows.Foundation.Metadata.Threading(Windows.Foundation.Metadata.ThreadingModel.Both)]
class VisualStateManager : DependencyObject
[Windows.Foundation.Metadata.ContractVersion(typeof(Windows.Foundation.UniversalApiContract), 65536)]
[Windows.Foundation.Metadata.MarshalingBehavior(Windows.Foundation.Metadata.MarshalingType.Agile)]
[Windows.Foundation.Metadata.Threading(Windows.Foundation.Metadata.ThreadingModel.Both)]
public class VisualStateManager : DependencyObject
Public Class VisualStateManager
Inherits DependencyObject
繼承
Object IInspectable DependencyObject VisualStateManager
屬性

Windows 需求

裝置系列
Windows 10 (已於 10.0.10240.0 引進)
API contract
Windows.Foundation.UniversalApiContract (已於 v1.0 引進)

範例

此範例示範如何使用 VisualStateManager.VisualStateGroups XAML 附加屬性。 請注意,未定義 「VisualStateManager」 標籤的方式。 在概念上,VisualStateManager.VisualStateGroups 包含控制項的視覺狀態,做為控制項範本中範本根目錄的直接子標記。

特定視覺狀態集包含一個名為 「CommonStates」 的 VisualStateGroup,其定義 「PointerOver」 和 「Normal」 VisualState 物件。 當使用者將指標放在 Button上方時, Grid 會以 .5 秒從綠色變更為紅色。 當使用者將指標移開按鈕時, Grid 會立即變更回綠色。

<ControlTemplate TargetType="Button">
  <Grid >
    <VisualStateManager.VisualStateGroups>
      <VisualStateGroup x:Name="CommonStates">

        <VisualStateGroup.Transitions>

          <!--Take one half second to transition to the PointerOver state.-->
          <VisualTransition To="PointerOver" 
                              GeneratedDuration="0:0:0.5"/>
        </VisualStateGroup.Transitions>
        
        <VisualState x:Name="Normal" />

        <!--Change the SolidColorBrush, ButtonBrush, to red when the
            Pointer is over the button.-->
        <VisualState x:Name="PointerOver">
          <Storyboard>
            <ColorAnimation Storyboard.TargetName="ButtonBrush" 
                            Storyboard.TargetProperty="Color" To="Red" />
          </Storyboard>
        </VisualState>
      </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Grid.Background>
      <SolidColorBrush x:Name="ButtonBrush" Color="Green"/>
    </Grid.Background>
  </Grid>
</ControlTemplate>
<common:LayoutAwarePage>
  <Grid>
...
    <VisualStateManager.VisualStateGroups>
    <!-- Visual states reflect the application's window size -->
      <VisualStateGroup>
        <VisualState x:Name="DefaultLayout">
           <Storyboard>
           </Storyboard>
        </VisualState>
        <VisualState x:Name="Below768Layout">
           <Storyboard>
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)"
               Storyboard.TargetName="ContentRoot">
               <DiscreteObjectKeyFrame KeyTime="0">
                 <DiscreteObjectKeyFrame.Value>
                   <Thickness>20,20,20,20</Thickness>
                 </DiscreteObjectKeyFrame.Value>
               </DiscreteObjectKeyFrame>
             </ObjectAnimationUsingKeyFrames>
             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.HorizontalAlignment)"
               Storyboard.TargetName="FooterPanel">
               <DiscreteObjectKeyFrame KeyTime="0">
                 <DiscreteObjectKeyFrame.Value>
                    <HorizontalAlignment>Left</HorizontalAlignment>
                 </DiscreteObjectKeyFrame.Value>
               </DiscreteObjectKeyFrame>
             </ObjectAnimationUsingKeyFrames>
           </Storyboard>
         </VisualState>
       </VisualStateGroup>
     </VisualStateManager.VisualStateGroups>
   </Grid>
</common:LayoutAwarePage>

下一個程式碼片段是要與 XAML 一起執行的程式碼,其中顯示應用程式如何偵測應用程式視窗寬度,並使用該資訊來呼叫適當的視覺狀態。

String state = (Window.Current.Bounds.Width > 768) ? "DefaultLayout" : "Below768Layout";
VisualStateManager.GoToState(this, state, false); // 'this' is the LayoutAwarePage, scope is page code-behind

備註

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

  • 控制項作者或應用程式開發人員使用VisualStateManager.VisualStateGroups附加屬性,將VisualStateGroup物件元素新增至 XAML 中控制項範本定義的根項目。 在 VisualStateGroup 元素內,每個 VisualState 都代表控制項的離散視覺狀態。 每個 VisualState 都有一個名稱,代表使用者可變更的 UI 狀態,或由控制項邏輯變更。 VisualState 主要包含 分鏡腳本。 此分鏡腳本的目標是個別的相依性屬性值變更,每當控制項處於該視覺狀態時,就應該套用這些變更。 如需如何在 XAML 中撰寫視覺狀態的詳細資訊,包括範例程式碼,請參閱 視覺狀態的腳本動畫
  • 呼叫 VisualStateManager 的靜態 GoToState 方法,控制這些狀態之間的作者或應用程式開發人員轉換。 每當控制項邏輯處理指出狀態變更的事件,或控制項邏輯自行起始狀態變更時,控制項作者就會執行此動作。 控制項定義程式碼通常會執行此動作,而不是應用程式程式碼,因此應用程式程式碼預設會有所有可能的視覺狀態及其轉換和觸發條件,而且邏輯會由 控制項封裝。

大部分開發人員只會使用兩個 VisualStateManager API:VisualStateManager.VisualStateGroups 和 GoToState,如上所述。 其餘的 API 全都適用于延伸模組支援,並建立自訂 VisualStateManager。 For more info see the "Custom VisualStateManager" section in this topic.

當您編輯 Microsoft Visual Studio XAML 設計介面所啟用的樣式複本時,預設範本中的視覺狀態會定義在您編輯的 XAML 中。 請確定您不會刪除這些狀態或變更其名稱,因為控制項邏輯預期這些視覺狀態存在於範本中。

除了視覺狀態之外,視覺狀態模型也包含轉換。 轉換是由 腳本 所控制的動畫動作,這些動作會在狀態變更時于每個視覺狀態之間發生。 您可以針對控制項的一組視覺狀態所定義的開始狀態和結束狀態組合,以不同的方式定義轉換。 轉換是由 VisualStateGroup 的 Transitions 屬性所定義,在 XAML 中使用屬性元素語法。 大部分的預設控制項範本不會定義轉換。 如果沒有明確定義的轉換,狀態之間的轉換會立即 (零持續時間) 發生。 如需詳細資訊,請參閱 VisualTransition

自訂 VisualStateManager

如果您想要實作自己的邏輯來轉換狀態 (進階案例) ,您可以建立繼承自 VisualStateManager 的類別。 請遵循這些方針:

  • 衍生類別應該覆寫受保護的 GoToStateCore 方法。 呼叫自訂VisualStateManager 的任何實例時,都會使用此Core邏輯。
  • 若要參考自訂 VisualStateManager 類別,請在您想要使用自訂 VisualStateManager 類別行為的ControlTemplate根項目上設定VisualStateManager.CustomVisualStateManager附加屬性的值,以及定義範本視覺狀態的VisualStateManager.VisualStateGroups附加屬性使用方式。 您通常會透過 Application.Resources中的預設 XAML 建構,建立自訂 VisualStateManager 類別的實例。 然後 ,VisualStateManager.CustomVisualStateManager 附加屬性是使用自訂 VisualStateManager 資源的索引鍵 {StaticResource} 標記延伸 參考來設定。

這是建立和使用自訂 VisualStateManager 的基本需求。 您也可以選擇覆寫更多行為:

所有其他 API (CustomVisualStateManagerPropertyGetCustomVisualStateManagerGetVisualStateGroupsSetCustomVisualStateManager) 都是附加屬性支援的基礎結構,而且您不需要呼叫它們或對其執行任何動作。

不是控制項之專案的視覺狀態

有時候,視覺狀態對於您想要變更某些 UI 區域的狀態不是立即 成為 Control 子類別的案例很有用。 您無法直接執行這項操作,因為GoToState方法的控制項參數需要Control子類別,這是指 VisualStateManager 作用的物件。 PageControl 子類別,而且您很少會在沒有 Page的內容中顯示 UI,或者 Window.Content 根目錄不是 Control 子類別。 我們建議您將自訂 UserControl 定義為 Window.Content 根目錄,或是您想要將狀態套用至 (的容器,例如 Panel) 。 然後,您可以在UserControl上呼叫GoToState,並套用狀態,而不論其餘的內容是否為Control。 例如,您可以將視覺狀態套用至只包含 SwapChainPanel 的 UI,只要您將它放在 UserControl 中,並宣告要套用至父 UserControl 或範本中具名 SwapChainPanel 部分的屬性的具名狀態即可。

XAML 附加屬性

VisualStateManager 是數個 XAML 附加屬性的主機服務類別。

為了支援 XAML 處理器對附加屬性的存取,以及公開對等 的 getset 作業給程式碼,每個 XAML 附加屬性都有一對 Get 和 Set 存取子方法。 在程式碼中取得或設定值的另一種方式是使用相依性屬性系統,呼叫 GetValueSetValue 並將識別碼欄位傳遞為相依性屬性識別碼。

附加屬性Description
VisualStateGroups 取得範本定義之根項目所定義的 VisualStateGroup 專案集合。 控制項通常會將其定義為其範本的一部分。

在程式碼中取得此屬性時,請使用 GetVisualStateGroups。 這會傳回集合物件,您可以將專案加入其中。 這會平行處理 VisualStateManager.VisualStateGroups 屬性元素使用方式之任何子項目的 XAML 處理行為。

因為這個特定附加屬性沒有公用相依性屬性識別碼,所以您無法使用 GetValue 來取得這個附加屬性值,所以您一律必須使用 GetVisualStateGroups。

CustomVisualStateManager 取得或設定自訂 VisualStateManager 物件,該物件會處理控制項狀態之間的轉換。

建構函式

VisualStateManager()

初始化 VisualStateManager 類別的新實例。

屬性

CustomVisualStateManagerProperty

識別 VisualStateManager.CustomVisualStateManager 相依性屬性。

Dispatcher

取得這個 物件相關聯的 CoreDispatcherCoreDispatcher代表可在 UI 執行緒上存取DependencyObject的功能,即使程式碼是由非 UI 執行緒起始也一樣。

(繼承來源 DependencyObject)

附加屬性

CustomVisualStateManager

取得或設定自訂 VisualStateManager 物件,該物件會處理控制項狀態之間的轉換。

方法

ClearValue(DependencyProperty)

清除相依性屬性的本機值。

(繼承來源 DependencyObject)
GetAnimationBaseValue(DependencyProperty)

傳回為相依性屬性建立的任何基底值,如果動畫未使用中,則適用此屬性。

(繼承來源 DependencyObject)
GetCustomVisualStateManager(FrameworkElement)

取得 VisualStateManager.CustomVisualStateManager 附加屬性的值。

GetValue(DependencyProperty)

DependencyObject傳回相依性屬性的目前有效值。

(繼承來源 DependencyObject)
GetVisualStateGroups(FrameworkElement)

擷取與指定之 FrameworkElement相關聯的VisualStateGroup物件集合。

GoToState(Control, String, Boolean)

藉由依名稱要求新的 VisualState ,轉換兩種狀態之間的控制項。

GoToStateCore(Control, FrameworkElement, String, VisualStateGroup, VisualState, Boolean)

在衍生類別中覆寫時,在狀態之間轉換控制項。

RaiseCurrentStateChanged(VisualStateGroup, VisualState, VisualState, Control)

在衍生類別中覆寫時,會在指定的VisualStateGroup 上引發 CurrentStateChanged事件

RaiseCurrentStateChanging(VisualStateGroup, VisualState, VisualState, Control)

在衍生類別中覆寫時,會在指定的VisualStateGroup 上引發 CurrentStateChanging事件

ReadLocalValue(DependencyProperty)

如果已設定本機值,則傳回相依性屬性的本機值。

(繼承來源 DependencyObject)
RegisterPropertyChangedCallback(DependencyProperty, DependencyPropertyChangedCallback)

註冊通知函式,以接聽此DependencyObject實例上特定DependencyProperty的變更。

(繼承來源 DependencyObject)
SetCustomVisualStateManager(FrameworkElement, VisualStateManager)

設定 VisualStateManager.CustomVisualStateManager 附加屬性的值。

SetValue(DependencyProperty, Object)

設定 DependencyObject上相依性屬性的本機值。

(繼承來源 DependencyObject)
UnregisterPropertyChangedCallback(DependencyProperty, Int64)

取消先前透過呼叫 RegisterPropertyChangedCallback註冊的變更通知。

(繼承來源 DependencyObject)

適用於

另請參閱