ViewStateManager的好处  拥有 GeneratedDuration ,可以很方便的进行几个状态之间的切换过渡动画。

坏处是,在界面加载时只能显示默认效果,通过GoToStateAction 绑定的DataTrigger 必须在界面加载完毕后触发才有效果。

-------下面为转载http://www.th7.cn/Program/net/201212/115057.shtml

    [TemplateVisualState(Name = "Large", GroupName = "SizeStates")]
[TemplateVisualState(Name = "Small", GroupName = "SizeStates")]
[TemplateVisualState(Name = "Inactive", GroupName = "ActiveStates")]
[TemplateVisualState(Name = "Active", GroupName = "ActiveStates")]

目录

  • 1. Trigger的支持
  • 2. 为什么是Trigger?
  • 3. ViewStateManager的支持
  • 4. Trigger和ViewStateManager的具体比较

返回目录

1. Trigger的支持

Trigger是XAML中另一个非常有趣的特性,它就像是在XAML中定义了一个if语句。但是随着后期微软XAML框架的演变,Trigger却逐渐被弱化,让我们先看看Trigger在当前最新XAML框架中的支持状况:

  WPF 4.5 Silverlight 5/WP8 WinRT(Windows 8)
FrameworkElement.Triggers 
(注意这里只支持EventTrigger)
支持 支持 支持
Style.Triggers 支持 不支持 不支持
DataTempate.Triggers 支持 不支持 不支持
ControlTemplate.Triggers 支持 不支持 不支持
Trigger类型 支持 不支持 不支持
EventTrigger类型 支持 支持 支持
DataTrigger类型 支持 不支持 不支持
TriggerBase.Enter/ExitActions 支持 不支持 不支持
BeginStoryboard TriggerAction 支持 支持 支持

看到了吧,Trigger在后期微软XAML框架中已经被大大削减,说实话只有WPF才能算上是支持Trigger的,而Silverlight/WinRT也就仅仅是在FrameworkElement的Trigges属性中支持BeginStoryboard这个TriggerAction罢了。

注意:

Microsoft Expression Blend SDK可以提供额外的对Trigger相关类型的支持。比如众所周知的System.Windows.Interactivity.dll。

返回目录

2. 为什么是Trigger?

OK,那么为什么Trigger在后期XAML框架混的这么惨呢?

我个人认为两点:

1:Trigger本身不是100%必须的,而后期的XAML框架显然很重视性能和体积,因此某些不是100%需要的东西就可能被剪掉。

比如模板中的Trigger可以通过定义Converter甚至是DataTemplateSelector代替,而Style中的Trigger通常比较少见,即便有需求也可以直接写在背后控件属性逻辑上,可以不放在XAML中。

2:Trigger多应用在动画定义上,在这一点上。从上面可以看到,EventTrigger和BeginStoryboard都被现有XAML框架所支持。不过在控件模板这种对动画定义需求比较高的情况下,BeginStoryboard很力不从心,而ViewStateManager在这里则完胜Trigger。

返回目录

3. ViewStateManager的支持

注意:

XAML中的ViewState和ASP.NET中的ViewState概念不一样,ASP.NET中的ViewState主要是指数据在无状态协议中的保留问题。而XAML中的ViewState指控件在不同状态下的外表定义。

ViewStateManager只有在某些旧的XAML框架中不支持,新的XAML框架都是很好地支持它的。

不支持ViewStateManager的XAML框架:

WPF 3.0

WPF 3.5

Silverlight 1

Silverlight 2

支持ViewStateManager的XAML框架:

WPF 4 +

Silverlight 3 +

Windows Phone 7.0 +

WinRT

可以看到,VisualStateManager基本上已经是任何XAML框架定义控件模板的标准了。

返回目录

4. Trigger和ViewStateManager的具体比较

接下来我们就来直接来比较一下Trigger和ViewStateManager的风格。我们就用最常见的操作:“控件模板”定义做比较。这也是他们的直接冲突领域。现在我们就定义一个最简单的Button的控件模板,具体规格如下:

1. 颜色默认是蓝色,鼠标指向时变成绿色,点击后变成灰色。

2. 要求点击后动画时长0.1秒,其他统一0.5秒。

注意:

下方代码统一以WPF环境做示例。因为WPF是唯一的既完全支持Trigger也支持ViewStateManager的XAML框架。

使用ViewStateManager方式:

1. 定义ViewStateGroup。

2. 定义具体ViewState

3. 添加Storyboard

4. 需要的话,定义Transition。

XAML:

<Button Content="Mgen">

<Button.Template>

<ControlTemplate TargetType="Button">

<Border Name="border"

Background="LightBlue">

<ContentPresenter Content="{TemplateBinding Content}"/>

<VisualStateManager.VisualStateGroups>

<!-- 普通状态 -->

<VisualStateGroup x:Name="CommonStates">

<!-- 定义时常 -->

<VisualStateGroup.Transitions>

<VisualTransition GeneratedDuration="0:0:0.5"/>

<VisualTransition GeneratedDuration="0:0:0.1" To="Pressed"/>

</VisualStateGroup.Transitions>

<!-- 定义三种状态的Storyboard -->

<VisualState x:Name="Normal"/>

<VisualState x:Name="MouseOver">

<Storyboard>

<ColorAnimation Storyboard.TargetName="border"

Storyboard.TargetProperty="Background.Color"

Duration="0"

To="Green"/>

</Storyboard>

</VisualState>

<VisualState x:Name="Pressed">

<Storyboard>

<ColorAnimation Storyboard.TargetName="border"

Storyboard.TargetProperty="Background.Color"

Duration="0"

To="Gray"/>

</Storyboard>

</VisualState>

</VisualStateGroup>

</VisualStateManager.VisualStateGroups>

</Border>

</ControlTemplate>

</Button.Template>

</Button>

而使用Trigger的方式:

注意:

尽管WPF对Trigger和ViewStateManager都完全支持。但是在WPF 4后,还是推荐使用ViewStateManager的方式定义模板。

使用Trigger定义,我们不得不面对如下麻烦:

1. 选择Trigger类型和对应属性,比如我们使用普通Trigger对象,和Button的IsPressed属性和IsMouseOver来手动判断状态。

2. 根据Trigger类型执行操作,如果使用Trigger.Setters,是具有自动还原功能的,如果使用EnterActions,如果想进行还原操作,必须设置ExitActions。对于EventTrigger,只能使用Actions属性。

3. 使用BeginStoryboard执行Storyboard,这里没有VisualStateManager模式中的GeneratedDuration,一切都得自己定义。

XAML:

<Button Content="Mgen">

<Button.Template>

<ControlTemplate TargetType="Button">

<Border Name="border" Background="LightBlue">

<ContentPresenter/>

</Border>

<!-- 定义Trigger -->

<ControlTemplate.Triggers>

<!-- 鼠标进入的设置和还原动画 -->

<Trigger Property="IsMouseOver" Value="True">

<Trigger.EnterActions>

<BeginStoryboard>

<Storyboard>

<ColorAnimation Storyboard.TargetName="border"

Storyboard.TargetProperty="Background.Color"

To="Green"

Duration="0:0:0.5"/>

</Storyboard>

</BeginStoryboard>

</Trigger.EnterActions>

<Trigger.ExitActions>

<BeginStoryboard>

<Storyboard>

<ColorAnimation Storyboard.TargetName="border"

Storyboard.TargetProperty="Background.Color"

Duration="0:0:0.5"/>

</Storyboard>

</BeginStoryboard>

</Trigger.ExitActions>

</Trigger>

<!-- 鼠标按下的设置和还原动画 -->

<Trigger Property="IsPressed" Value="True">

<Trigger.EnterActions>

<BeginStoryboard>

<Storyboard>

<ColorAnimation Storyboard.TargetName="border"

Storyboard.TargetProperty="Background.Color"

To="Gray"

Duration="0:0:0.1"/>

</Storyboard>

</BeginStoryboard>

</Trigger.EnterActions>

<Trigger.ExitActions>

<BeginStoryboard>

<Storyboard>

<ColorAnimation Storyboard.TargetName="border"

Storyboard.TargetProperty="Background.Color"

Duration="0:0:0.5"/>

</Storyboard>

</BeginStoryboard>

</Trigger.ExitActions>

</Trigger>

</ControlTemplate.Triggers>

</ControlTemplate>

</Button.Template>

</Button>

结果很明显,使用Trigger和ViewStateManager相比,Trigger的方式更原始,可能会依靠多种Trigger的多种执行方式来完成设置操作,动画定义较繁琐。而ViewStateManager,则是为了克服如上缺点而生。

当然,ViewStateManager也有其不好的一面,有些时候,特别是不需要动画的时候,ViewStateManager只能还是使用动画的模式硬生生地进行非动画操作。比如我们创建一个简单的CheckBox的控件模板。当选中后显示“真”,未选时显示“假”。

使用ViewStateManager方式。我们还得定义Storyboard,只不过是用ObjectAnimationUsingKeyFrames。XAML:

<CheckBox IsChecked="False">

<CheckBox.Template>

<ControlTemplate TargetType="CheckBox">

<Border>

<TextBlock Text="真" Name="textBlock"/>

<VisualStateManager.VisualStateGroups>

<VisualStateGroup Name="CheckStates">

<VisualState Name="Checked"/>

<VisualState Name="Unchecked">

<Storyboard>

<ObjectAnimationUsingKeyFrames Duration="0"

Storyboard.TargetName="textBlock"

Storyboard.TargetProperty="Text">

<DiscreteObjectKeyFrame KeyTime="0"

Value="假"/>

</ObjectAnimationUsingKeyFrames>

</Storyboard>

</VisualState>

</VisualStateGroup>

</VisualStateManager.VisualStateGroups>

</Border>

</ControlTemplate>

</CheckBox.Template>

</CheckBox>

这个时候,我们就该想念Trigger,一个再简单不过的Trigger和一个Setter就实现了上述功能,既简单可读性还高,XAML:

<CheckBox IsChecked="False">

<CheckBox.Template>

<ControlTemplate TargetType="CheckBox">

<Border>

<TextBlock Text="真" Name="textBlock"/>

</Border>

<ControlTemplate.Triggers>

<Trigger Property="IsChecked" Value="False">

<Setter TargetName="textBlock"

Property="Text"

Value="假"/>

</Trigger>

</ControlTemplate.Triggers>

</ControlTemplate>

</CheckBox.Template>

</CheckBox>

当然,多数情况下VisualStateManager还是完胜Trigger方式的,毕竟有动画的控件模板更受欢迎!不过如果Trigger被加入到Silverlight和WinRT中也不错,因为在某些时候,开发者又有一种新的选择!

Trigger和ViewStateManager的具体比较的更多相关文章

  1. trigger事件模拟

    事件模拟trigger 在操作DOM元素中,大多数事件都是用户必须操作才会触发事件,但有时,需要模拟用户的操作,来达到效果. 需求:页面初始化时触发搜索事件并获取input控件值,并打印输出(效果图如 ...

  2. Oracle数据库自动备份SQL文本:Procedure存储过程,View视图,Function函数,Trigger触发器,Sequence序列号等

    功能:备份存储过程,视图,函数触发器,Sequence序列号等准备工作:--1.创建文件夹 :'E:/OracleBackUp/ProcBack';--文本存放的路径--2.执行:create or ...

  3. jQuery之常用且重要方法梳理(target,arguments,slice,substring,data,trigger,Attr)-(一)

    1.jquery  data(name) data() 方法向被选元素附加数据,或者从被选元素获取数据. $("#btn1").click(function(){ $(" ...

  4. [UWP]创建自定义VisualState Trigger

    这篇博客将介绍在UWP程序中如何创建和使用自定义VisualState Trigger. 上一篇博客中介绍了如何使用AdaptiveTrigger.目前UWP内置的StateTrigger只有Adap ...

  5. trigger() --工作中问题nav样式

    自动执行某元素的某个事件 $("#div").trigger("click");  //让系统自动执行单击事件 适用于nav样式中,下面横线绝对定位于nav.o ...

  6. 页面加载完成后,触发事件——trigger()

    <button id="btn">点击我</button> <div id="test"></div> 如果页面 ...

  7. mysql之触发器trigger

    触发器(trigger):监视某种情况,并触发某种操作. 触发器创建语法四要素:1.监视地点(table) 2.监视事件(insert/update/delete) 3.触发时间(after/befo ...

  8. oracle 备份数据库对象(存储过程PROCEDURE,FUNCTION,VIEW,TRIGGER...)

    开发过程中,需要不停的备份数据库对象, 特别是存储过程, 每次手动备份不免很低能啊 历经几次修改终于, 完美了,O(∩_∩)O哈哈~      (当然,你也可以再改简便一点~~~) select db ...

  9. salesforce 零基础学习(五十二)Trigger使用篇(二)

    第十七篇的Trigger用法为通过Handler方式实现Trigger的封装,此种好处是一个Handler对应一个sObject,使本该在Trigger中写的代码分到Handler中,代码更加清晰. ...

随机推荐

  1. tfs连不上团队资源管理器问题

    这个问题主要原因是因电脑装了vs2008又装了vs2012,因为版本不一样,所以只需要将VersionControl.config这个文件删除掉就可以了.文件路径C:\Users\Administra ...

  2. Javascript设计模式学习一

    学习Javascript设计模式之前,需要先了解一些相关知识,面向对象的基础知识.this等重要概念,以及掌握一些函数式编程的技巧. Js多态 多态的思想:实际上是把“做什么”和“谁去做”分离开来.例 ...

  3. Learning Spark 第四章——键值对处理

    本章主要介绍Spark如何处理键值对.K-V RDDs通常用于聚集操作,使用相同的key聚集或者对不同的RDD进行聚集.部分情况下,需要将spark中的数据记录转换为键值对然后进行聚集处理.我们也会对 ...

  4. 为什么要用base64编码

    1.需求 了解为什么要使用base64对数据编码 2.理由 因为传输二进制数据的时候,网络中间的有些路由会把ascii码中的不可见字符删了,导致数据不一致.一般也会对url进行base64编码 Whe ...

  5. windows7 gvim 配置(好用)

    http://blog.csdn.net/anders_zhuo/article/details/8949003

  6. 超详细Web前端开发规范文档

    http://www.w3cfuns.com/notes/26488/c2ae788c77f835357025026a148b9863.html

  7. sublime自动生成头部注释

    1.在tool->new snippet-创建一个新的snippet sublime text2 用snippet 创建文件头部信息 Snippets are smart templates t ...

  8. 【TortoiseGit】TortoiseGit将本地库push到远端

    以前也在使用GitHub,2年前电脑上就装了TortoiseGit和SVN,公司也在用Git,但是并没有刻意去做一些事情,未免觉得有些生疏,今天闲来无聊.玩了一把.[做中成长] 对于GitToiseG ...

  9. Python3实现火车票查询工具

    Python 实现火车票查询工具 一. 实验介绍 通过python3实现一个简单的命令行版本的火车票查询工具,用实际中的例子会更感兴趣,不管怎么样,既练习了又可以自己使用. 1.  知识点: Pyth ...

  10. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...