VisualStateManager 類別

定義

管理視覺狀態及控制項視覺狀態間轉換的邏輯。 同時也提供了附加屬性支援, VisualStateManager.VisualStateGroups這是你如何在 XAML 中定義控制範本的視覺狀態。

/// [Windows.Foundation.Metadata.ContractVersion(Microsoft.UI.Xaml.WinUIContract, 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(Microsoft.UI.Xaml.WinUIContract), 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
屬性

範例

這個範例展示了如何使用 VisualStateManager.VisualStateGroups XAML attached 屬性。 請注意,遊戲中並未定義「VisualStateManager」標籤。 概念上,包含 VisualStateManager.VisualStateGroups 控制項的視覺狀態,作為控制模板根的直接子標籤。

這組特定的視覺狀態包含一個稱為「CommonStates」的 VisualStateGroup,定義了「PointerOver」與「Normal」 VisualState 物件。 當使用者將指標放在 按鈕上時, 格子 會在0.5秒內從綠色變為紅色。 當使用者將指標移離按鈕時, 格子 會立刻變回綠色。

<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 UI 狀態都有一個名稱,代表使用者可更改或控制邏輯的 UI 狀態。 A VisualState 主要包含分 圖。 此方法 Storyboard 針對個別相依屬性值的變更,應在控制處於該視覺狀態時套用。
  • 控制項作者或應用程式開發者透過呼叫靜態 GoToState 方法 VisualStateManager在這些狀態間切換。 控制權作者會在控制邏輯處理表示狀態變更的事件,或控制邏輯自行發起狀態變更時,進行此操作。 控制定義程式碼比應用程式程式碼更常見,因此所有可能的視覺狀態、轉換和觸發條件預設在應用程式程式碼中,邏輯則由控制項封裝。

大多數開發者只會使用其中兩個 VisualStateManager API: VisualStateManager.VisualStateGroups以及如上所述的 GoToState。 剩下的 API 都是用於擴充功能支援及建立自訂 VisualStateManager的 。 更多資訊請參考本主題中的「自訂 VisualStateManager」章節。

當你編輯 Microsoft Visual Studio XAML 設計表面啟用的樣式副本時,預設模板的視覺狀態會在你正在編輯的 XAML 中定義。 確保你不要刪除這些狀態或更改它們的名稱,因為控制邏輯預期這些視覺狀態存在於模板中。

除了視覺狀態外,視覺狀態模型還包含轉換。 轉場是由 分鏡 控制的動畫動作,當狀態改變時,會在每個視覺狀態之間發生。 轉換可以根據你控制組的視覺狀態組合,根據起始狀態和結束狀態的組合來定義不同的方式。 轉換由 的 VisualStateGroupTransitions 屬性定義,使用 XAML 中的 Transitions 屬性,並使用屬性元素語法。 大多數預設控制範本並未定義轉換。 在缺乏明確定義的轉移的情況下,狀態間的轉移是瞬間發生的(零持續時間)。 更多資訊請參見 VisualTransition

Custom VisualStateManager

如果你想實作自己進行狀態轉換的邏輯(進階情境),你可以建立一個繼承自 VisualStateManager的類別。 請遵循以下準則:

  • 衍生類別應該會覆寫受保護的 GoToStateCore 方法。 任何自訂VisualStateManager實例在呼叫其 GoToState 方法時都會使用這個核心邏輯。
  • 要參考你的自訂VisualStateManager類別,請在你想使用自訂VisualStateManager類別行為的 ControlTemplate 根元素上設定附加VisualStateManager.CustomVisualStateManager屬性的值,並VisualStateManager.VisualStateGroups搭配定義範本視覺狀態的附加屬性使用方式。 你通常透過 Application.Resources 的預設 XAML 建構來建立自訂VisualStateManager類別的實例。 接著,附加屬性 VisualStateManager.CustomVisualStateManager 會透過 {StaticResource} 標記擴充名 來設定自訂資源的 VisualStateManager 鍵。

這就是建立和使用自訂 VisualStateManager. 你也可以選擇覆蓋幾個額外的行為:

其他所有 API(CustomVisualStateManagerPropertyGetCustomVisualStateManagerGetVisualStateGroupsSetCustomVisualStateManager)都是支援附加屬性的基礎架構,你不需要呼叫它們或做任何操作。

非控制項元素的視覺狀態

視覺狀態有時對於想改變 UI 中某個非 Control 子類別區域狀態的情境很有用。 你無法直接這麼做,因為 GoToState 方法的控制參數需要一個Control子類別,而子類別指的是 VisualStateManager 所作用的物件。 Page 是一個 Control 子類別,而且你很少會在沒有 Page、 或你的 Window.Content 根節點不是 Control 子類別的情況下顯示 UI。 我們建議你定義一個自訂 的 UserControl ,要麼是 Window.Content 根目錄,要麼是你想套用狀態的其他內容(例如 Panel)的容器。 然後你可以在你的 UserControlGoToState 上呼叫並套用州,不管其他內容是否是 Control。 例如,你可以將視覺狀態套用到原本只有 SwapChainPanel 的 UI 裡,只要你把它放在 UserControl 你並宣告的命名狀態裡,這些狀態套用到父 UserControl 或模板中命名 SwapChainPanel 部分的屬性。

XAML 附加屬性

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

為了支援 XAML 處理器對附加屬性的存取,並讓程式碼中暴露等效 的取得設定 操作,每個 XAML 附加屬性都有一對 GetSet 存取器方法。 另一種在程式碼中取得或設定值的方法是使用相依屬性系統,呼叫 GetValueSetValue ,並將識別欄位傳入相依屬性識別碼。

附加屬性Description
視覺狀態群組 取得由範本定義根元素定義的 VisualStateGroup 元素集合。 控制項通常會將其定義為其範本的一部分。

在程式碼中取得這個屬性時,請使用 GetVisualStateGroups。 這會回傳一個集合物件,你可以在裡面新增項目。 這與 VisualStateManager.VisualStateGroups 屬性元素中任何子元素的 XAML 處理行為平行。

由於這個附加屬性沒有公開的相依屬性識別碼,你無法使用 GetValue 取得這個附加屬性值,你必須始終使用 GetVisualStateGroups。

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

這個附加的屬性只在你想用自訂實作類別來處理應用程式視覺狀態變更,而非 Windows 執行階段 預設的 VisualStateManager 類別時才需要。 如果你不打算使用自訂實作,就不需要設定這個屬性。

建構函式

名稱 Description
VisualStateManager()

初始化 VisualStateManager 類別的新實例。

屬性

名稱 Description
CustomVisualStateManagerProperty

識別 VisualStateManager.CustomVisualStateManager 依賴屬性。

Dispatcher

它總是在 Windows 應用程式 SDK 應用程式中回傳 null 。 改用 DispatcherQueue

(繼承來源 DependencyObject)
DispatcherQueue

得到 DispatcherQueue 這個物件所關聯的那個。 代表 DispatcherQueue 一個功能,即使程式碼是由非 UI 執行緒發起,也能存取 UI DependencyObject 執行緒。

(繼承來源 DependencyObject)

附加屬性

名稱 Description
CustomVisualStateManager

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

方法

名稱 Description
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 attached 屬性的值。

SetValue(DependencyProperty, Object)

將相依屬性的局部值設定在 DependencyObject 上。

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

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

(繼承來源 DependencyObject)

適用於

另請參閱