概述

在WPF和Silverlight中的控件模板支持自定义控件的观感,所谓的外观,指控件的视觉效果;而感觉则是控件交互的响应性,如在控件上按下鼠标、控件获得焦点等状态的改变。微软在Silverlight 2 Beta 2中引进了一个新的概念视觉状态管理(Visual State Manager),为我们创建交互性的控件模板提供了极大的方便。接下来我将会用几篇文章来介绍一下Silverlight 2中的视觉状态管理。
在定义控件时,我们需要严格区分控件的视觉效果和控件的逻辑,这样当我们修改控件外观时将不会影响控件逻辑。Silverlight 2 Beta 2中提出的部件和状态模型,能够很好的解决这一问题,本文我们先来看一些基本的概念。

部件(Parts)

所谓的部件(Parts)是指在空间模板中元素,控件逻辑将会控制这些部件来完成一些特定的控件,但它并不关心这些部件的视觉效果,如下图所示对于一个Silder控件来说:
在上图中的Silder控件由四个部件构成:一个名为HorizontalThumb的Thumb控件,一个名为HorizontalLargeChangeIncrease的RepeatButton控件,一个名为HorizontalLargeChangeDecrease的RepeatButton控件,一个名为HorizontalTemplate的FrameworkElement元素。这些元素都将会在控件逻辑中进行控制,如当按下HorizontalLargeChangeIncrease时滑块将向右移动,按下HorizontalLargeChangeDecrease时滑块将向左移动。
需要注意的一点是并不是所有的控件都具有部件,有些控件可能没有部件,大家可以去查阅Silverlight 2 SDK。

视觉状态(Visual States)

视觉状态是指控件定义的一系列状态如MouseOver、Pressed等,它代表了控件处于某一个特定的逻辑状态。如下面这幅图中定义的CheckBox控件的一些视觉状态:
默认状态下,CheckBox控件将显示为Normal状态;当CheckBox被选中时,它将显示为Checked状态;当Checked为null,CheckBox将显示为Indeterminate状态。
控件的视觉状态在Silverlight 2中会使用VisualState类来表示,它的定义非常简单如下代码所示:
public sealed class VisualState : DependencyObject
{public VisualState();public string Name { get; }public Storyboard Storyboard { get; set; }
}

状态迁移(State Transitions)

状态迁移是指控件从一个状态过渡到另外一个状态,如Button控件从MouseOver状态到Pressed状态这个过渡过程,通过Storyboard来定义的动画。
状态迁移在Silverlight 2中使用VisualTransition类来表示,它的定义如下代码所示:
public class VisualTransition
{public VisualTransition();public Duration Duration { get; set; }public string From { get; set; }public Storyboard Storyboard { get; set; }public string To { get; set; }
}

状态组(StateGroups)

状态组,是把控件所有互斥的状态放在同一个组中,这样一个状态它只能位于一个组中,所谓的互斥是指控件不肯能同时具有该组中的两种状态,如Checked和Unchecked两个状态不可能同时存在。以CheckBox控件为例,我们来看一下它的状态组:
 
从上表中我们可以看到,对于CheckBox控件来说,它有三个状态组:FocusStates、CommonStates、CheckStates。一个CheckBox控件可以同时为Focused、MouseOver和Indeterminate状态,因为它们处在不同的状态组。现在对于这个问题:“CheckBox控件的状态是什么?”答案应该由三部分组成,分别为三个状态组中的一个。状态组是在Silverlight 2中提出的一个新的概念,它由VisualStateGroup类来提供,其中除了状态组名属性外,维护了一个视觉状态的集合和一个状态迁移的集合,如下代码所示:
public sealed class VisualStateGroup : DependencyObject
{public VisualStateGroup();public string Name { get; }public Collection<VisualState> States { get; set; }public Collection<VisualTransition> Transitions { get; set; }
}
使用状态组是一个非常棒的模型,在Beta 1中,CheckBox控件有12种状态(其中Focus在Beta 1中是作为部件而不是状态),这12种状态是通过CommonStates和CheckStates组合而成的,如PressedUnchecked、MouseOverChecked等,而在Beta 2中,加上FocusStates状态,CheckBox控件总共只有10种状态。
控件的状态和状态组是通过TemplateVisualState特性来声明的,如在CheckBox控件中的声明如下代码所示:
[TemplateVisualStateAttribute(Name = "ContentFocused", GroupName = "FocusStates")]
[TemplateVisualStateAttribute(Name = "MouseOver", GroupName = "CommonStates")]
[TemplateVisualStateAttribute(Name = "Focused", GroupName = "FocusStates")]
[TemplateVisualStateAttribute(Name = "Checked", GroupName = "CheckStates")]
[TemplateVisualStateAttribute(Name = "Unchecked", GroupName = "CheckStates")]
[TemplateVisualStateAttribute(Name = "Indeterminate", GroupName = "CheckStates")]
[TemplateVisualStateAttribute(Name = "Pressed", GroupName = "CommonStates")]
[TemplateVisualStateAttribute(Name = "Disabled", GroupName = "CommonStates")]
[TemplateVisualStateAttribute(Name = "Unfocused", GroupName = "FocusStates")]
[TemplateVisualStateAttribute(Name = "Normal", GroupName = "CommonStates")]
public class CheckBox : ToggleButton
{ // ......
}

视觉状态管理器

我们再来看一下视觉状态管理器的概念,有了上面这些概念,在Silverlight 2中视觉状态管理是通过视觉状态管理器(Visual State Manager)来进行的,Silverlight 2中提供了VisualStateManager类,如下所示:
public class VisualStateManager : DependencyObject
{public static DependencyProperty CustomVisualStateManagerProperty;public VisualStateManager();public static VisualStateManager GetCustomVisualStateManager(DependencyObject obj);public static Collection<VisualStateGroup> GetVisualStateGroups(DependencyObject obj);public static bool GoToState(Control control, string stateName, bool useTransitions);protected virtual bool GoToStateCore(Control control, FrameworkElement templateRoot, string stateName, VisualStateGroup group, VisualState state, bool useTransitions);public static void SetCustomVisualStateManager(DependencyObject obj, VisualStateManager value);
}
视觉状态管理器负责管理控件的状态和状态组以及状态的迁移。

状态变化

外部事件触发将会引起状态的变化,进而引发状态迁移,整个过程如下流程图所示:

总结

本文介绍了Silverlight 2中视觉状态管理的一些基本概念,下篇文章,我们将结合实例看看如何使用视觉状态管理来定制控件的观感。
本文首发于IT168:[url]http://publish.itpub.net/msoft/2008-07-02/200807021455296.shtml[/url]
本文转自lihuijun51CTO博客,原文链接:http://blog.51cto.com/terrylee/86472 ,如需转载请自行联系原作者

谈谈Silverlight 2中的视觉状态管理 Part1相关推荐

  1. 在vue项目中引用vuex状态管理工具

    在vue项目中引用vuex状态管理工具 一.vuex是什么? 二.使用步骤 1.引入库 2.在main.js文件引入配置 3.配置store/index.js文件 4.获取state数据 5.获取ge ...

  2. qnetworkreply 获取状态_谈谈Unity Shader中的采样器状态和(Texture Filtering)纹理滤波方式

    参考文章: 使用采样器状态 - Unity 手册​docs.unity3d.comhttps://blog.csdn.net/chenjinxian_3D/article/details/518169 ...

  3. Vue中的Pinia状态管理工具 | 一篇文章教会你全部使用细节

    文章目录 Pinia状态管理 Pinia和Vuex的对比 Pinia基本使用

  4. Silverlight 属性样式、控件模板、视觉状态

    在使用Silverlight的样式的时候感觉非常好,以前在HTML上很难实现的效果在这里都变的如此简单. 属性样式 控件的属性样式好比CSS的Class功能定义,是用来统一定义和维护控件属性的方式,控 ...

  5. [译] ⚛ React 状态管理工具博物馆

    原文地址:⚛ The React State Museum: ⚡️View the hottest state management libs for React 原文作者:Gant Laborde ...

  6. flutter 局部状态和全局状态区别_Flutter状态管理

    Flutter状态管理 状态管理是声明式编程非常重要的一个概念,我们在前面介绍过Flutter是声明式编程的,也区分声明式编程和命令式编程的区别. 这里,我们就来系统的学习一下Flutter声明式编程 ...

  7. vue状态管理存取数据_vue状态管理vuex从浅入深详细讲解

    1.vuex简介以及创建一个简单的仓库 vuex是专门为vue框架而设计出的一个公共数据管理框架,任何组件都可以通过状态管理仓库数据沟通,也可以统一从仓库获取数据,在比较大型的应用中,数据交互庞大的情 ...

  8. 面向.NET开发人员的Dapr——状态管理

    目录: 面向.NET开发人员的Dapr--前言 面向.NET开发人员的Dapr--分布式世界 面向.NET开发人员的Dapr--俯瞰Dapr 面向.NET开发人员的Dapr--入门 面向.NET开发人 ...

  9. ASP.NET状态管理之一(概括篇)

    每次将网页发送到服务器时,都会创建网页类的一个新实例.在传统的Web编程中,这通常意味着在每一次往返行程中,与该页及该页上的控件相关联的所有信息都会丢失.例如,如果用户将信息输入到文本框,该信息将在从 ...

最新文章

  1. 哪怕你不认可,我还是要为R语言正名
  2. gg.gap:ggplot阶截断坐标轴的优秀完美解决方案
  3. 【Git】Git 分支管理 ( 解决分支合并冲突 | 创建并切换分支 git switch -c feature1 | 修改 feature1 分支并提交 | 修改 master 主版本并提交 )
  4. matlab绘图大全
  5. H5前端框架推荐合集 (转)
  6. C# Aes CryptoStream Specified padding mode is not valid for this algorithm的解決方法
  7. mysql封装 javabean,利用Java针对MySql封装的jdbc框架类JdbcUtils完整实现(包含增删改查、JavaBean反射原理,附源码)...
  8. Openstack基础架构和各组件的关系
  9. 作业计算机组成与原理,课程计算机组成原理与汇编语言作业四
  10. Android Activity设置全屏
  11. 深度学习 arm linux移植过程整理
  12. win7系统服务器管理器在哪里找,win7打开服务管理器
  13. dbv连oracle,oracle工具:DBV的用法
  14. 如何在南方CASS中内插高程点
  15. 【fences下载】
  16. Connection reset by peer 问题解析
  17. XGboost和GBDT的异同
  18. 基于python的opencv的学习
  19. 日期函数DATEDIFF() 计算日期之差
  20. 博客相关 | 如何获取图片主题色并修改字体颜色

热门文章

  1. Java HashMap工作原理深入探讨
  2. 深入了解MyBatis返回值
  3. linux 文本编辑命令grep sed awk
  4. Mybatis的ResultMap的使用
  5. OpenCV之core 模块. 核心功能(1)Mat - 基本图像容器 OpenCV如何扫描图像、利用查找表和计时 矩阵的掩码操作 使用OpenCV对两幅图像求和(求混合(blending))
  6. ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第二篇:第一个页面
  7. Deep Learning论文笔记之(一)K-means特征学习
  8. webservice 之 Java CXF实战效果 RS WS(二)
  9. Hibernate Tomcat JNDI数据源配置(转)
  10. WinRAR 注册方法