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. 关于unity如何制作mmo

    昨天去看了下unity的成都openday,还是有很多收获的,之前我对于这类的活动始终提不起来兴趣,不过看来日后还是要多参加下类似的活动长长见识. 公司打算开发3d mmo手游,昨天好玩123恰好也分 ...

  2. Linux 基础命令

    man      帮助命令   命令 --help   命令的简单帮助 help      命令的帮助(bash的内置命令) mkdir    创建目录  如makdir /data mkdir   ...

  3. php编译 :virtual memory exhausted: Cannot allocate memory

    有时候用vps建站时需要通过编译的方式来安装主机控制面板.对于大内存的VPS来说一般问题不大,但是对于小内存,比如512MB内存的VPS来说,很有可能会出现问题,因为编译过程是一个内存消耗较大的动作. ...

  4. 修改html页面文字选中样式

    ::selection { background-color: #31B0D5; color: #fff; text-shadow: 0 1px 0 rgba(0,0,0,.2); }

  5. VMware ubuntu中执行python文件的操作小结

  6. [BZOJ3223]Tyvj 1729 文艺平衡树

    [BZOJ3223]Tyvj 1729 文艺平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区 ...

  7. 创建table并实现ID自增长

    ① create table p_user( id               number(10) not null primary key, name             varchar2(3 ...

  8. input事件与change事件

    输入框的change事件: 必须等到输入框失去焦点的时候才会触发,鼠标在空白的地方点一下: 输入框的input事件: 在输入内容变化的同时,实时的触发,不需要等到失去焦点.

  9. bzoj 4695: 最假女选手

    ……一道丧病线段树膜板题…… 被常数卡的死去活来……QAQ 学到了些奇技淫巧:把取min标记 和 区间最小值 合并 可以快很多…… #include <bits/stdc++.h> #de ...

  10. 全排列算法的JS实现

    问题描述:给定一个字符串,输出该字符串所有排列的可能.如输入“abc”,输出“abc,acb,bca,bac,cab,cba”. 虽然原理很简单,然而我还是折腾了好一会才实现这个算法……这里主要记录的 ...