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 对象。 当用户将指针放在 按钮上时, 网格 在 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 表示控件的离散视觉状态。 每个 VisualState 都有一个代表可由用户更改或由控件逻辑更改的 UI 状态的名称。 VisualState 主要由 情节提要组成。 此情节提要面向当控件处于该视觉状态时应应用的单个依赖属性值更改。 有关如何在 XAML 中编写视觉状态(包括示例代码)的详细信息,请参阅 视觉状态的情节提要动画
  • 控件作者或应用开发人员通过调用 VisualStateManager 的静态 GoToState 方法在这些状态之间转换。 每当控件逻辑处理指示状态更改的事件或控件逻辑自行启动状态更改时,控件作者就会执行此操作。 控件定义代码更常见地执行此操作,而不是应用代码,这样,应用代码默认存在所有可能的视觉状态及其转换和触发条件,并且逻辑由控件封装。

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

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

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

自定义 VisualStateManager

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

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

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

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

非控件元素的视觉状态

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

XAML 附加属性

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

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

附加属性说明
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)

适用于

另请参阅