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 附加属性。 请注意,没有定义“VisualStateManager”标记。 从概念上讲, VisualStateManager.VisualStateGroups 包含控件的视觉状态,作为控件模板中模板根的直接子标记。

特定的视觉状态集包含一个名为“CommonStates”的 VisualStateGroup,该组定义“PointerOver”和“Normal” VisualState 对象。 当用户将指针悬停在 按钮上时, 网格 会在 0.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情节提要组成。 这 Storyboard 面向在控件处于该可视状态时应应用的单个依赖属性值更改。
  • 控件作者或应用开发人员通过调用 的VisualStateManager静态 GoToState 方法在这些状态之间转换。 每当控件逻辑处理指示状态更改的事件,或控件逻辑自行启动状态更改时,控件作者就会执行此操作。 控件定义代码更常见地执行此操作,而不是应用代码,以便应用代码默认存在所有可能的视觉状态及其转换和触发条件,并且逻辑由控件封装。

如前所述,大多数开发人员只使用两个 VisualStateManager API: VisualStateManager.VisualStateGroups、 和 GoToState。 其余 API 全部用于扩展支持和创建自定义 VisualStateManager。 有关详细信息,请参阅本主题中的“自定义 VisualStateManager”部分。

编辑由 Microsoft Visual Studio 的 XAML 设计图面启用的样式副本时,默认模板中的视觉状态是在你正在编辑的 XAML 中定义的。 请确保不要删除这些状态或更改其名称,因为控件逻辑预期模板中存在这些视觉状态。

除了视觉状态之外,视觉状态模型还包括转换。 切换是由 情节提要 控制的动画操作,在状态更改时在每个视觉状态之间发生。 对于由控件的视觉状态集定义的开始状态和结束状态的每种组合,可以以不同的方式定义转换。 转换由 的 Transitions 属性 VisualStateGroup定义,在 XAML 中使用属性元素语法。 大多数默认控件模板不定义转换。 如果没有专门定义的转换,状态之间的转换会瞬间发生 (持续时间为零的) 。 有关详细信息,请参阅 VisualTransition

自定义 VisualStateManager

如果要实现自己的逻辑,以便在状态之间转换 (高级方案) ,可以创建继承自 VisualStateManager的类。 请遵循这些指导:

  • 派生类应重写受保护的 GoToStateCore 方法。 任何自定义VisualStateManager实例在调用其 GoToState 方法时都使用此 Core 逻辑。
  • 若要引用自定义VisualStateManager类,请在要在其中使用自定义VisualStateManager类行为的 ControlTemplate 的根元素上设置附加属性的值VisualStateManager.CustomVisualStateManager,以及VisualStateManager.VisualStateGroups定义模板视觉状态的附加属性用法。 通常通过 Application.Resources 中的默认 XAML 构造创建自定义类的VisualStateManager实例。 然后,VisualStateManager.CustomVisualStateManager使用对自定义VisualStateManager资源的键的 {StaticResource} 标记扩展引用来设置附加属性。

这是创建和使用自定义 VisualStateManager的基本要求。 还可以选择替代其他一些行为:

所有其他 API (CustomVisualStateManagerPropertyGetCustomVisualStateManagerGetVisualStateGroupsSetCustomVisualStateManager) 都是附加属性支持的基础结构,无需调用它们或对其执行任何操作。

不是控件的元素的视觉状态

视觉状态有时适用于想要更改 UI 的某些区域(不是直接作为 Control 子类)的状态的方案。 不能直接执行此操作,因为 GoToState 方法的控件参数需要一个Control子类,该子类引用 VisualStateManager 作用的对象。 Page 是一个 Control 子类,很少在没有 Page的上下文中显示 UI,或者 Window.Content 根不是 Control 子类。 建议将自定义 UserControlWindow.Content 定义为要将状态应用到 (的其他内容的根或容器,例如 面板) 。 然后,无论内容的其余部分是否为 Control,都可以调用 GoToStateUserControl 并应用状态。 例如,可以将视觉状态应用于 UI,否则只包含 SwapChainPanel ,前提是将视觉 UserControl 状态放置在应用于模板的父 UserControl 级或命名部分的属性的和声明的命名 SwapChainPanel 状态中。

XAML 附加属性

VisualStateManager 是多个 XAML 附加属性的主机服务类。

为了支持 XAML 处理器对附加属性的访问,以及向代码公开等效Get get 和 set 操作,每个 XAML 附加属性都有一对 和 Set 访问器方法。 在代码中获取或设置值的另一种方法是使用依赖属性系统,调用 GetValueSetValue ,并将标识符字段作为依赖属性标识符传递。

附加属性说明
VisualStateGroups 获取由模板定义的根元素定义的 VisualStateGroup 元素的集合。 控件通常将其定义为其模板的一部分。

在代码中获取此属性时,请使用 GetVisualStateGroups。 这将返回一个集合对象,可向其添加项。 这与 VisualStateManager.VisualStateGroups 属性元素用法的任何子元素的 XAML 处理行为相似。

由于此特定附加属性没有公共依赖属性标识符,因此无法使用 GetValue 获取此附加属性值,因此始终必须使用 GetVisualStateGroups。

CustomVisualStateManager 获取或设置处理控件状态之间的转换的自定义 VisualStateManager 对象。

仅当你想要使用自定义实现类来处理应用的视觉状态更改时,才需要此附加属性,而不是Windows 运行时实现的默认 VisualStateManager 类。 如果不打算使用自定义实现,则无需设置此属性。

构造函数

VisualStateManager()

初始化 VisualStateManager 类的新实例。

属性

CustomVisualStateManagerProperty

标识 VisualStateManager.CustomVisualStateManager 依赖属性。

Dispatcher

始终在Windows 应用 SDK应用中返回 null 。 请改用 DispatcherQueue

(继承自 DependencyObject)
DispatcherQueue

获取 DispatcherQueue 与此 对象关联的 。 DispatcherQueue表示可以访问 DependencyObject UI 线程上的 的功能,即使代码是由非 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)

适用于

另请参阅