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. jQuery动画slideUp()不正常位移原因

    用jQuery写一个列表.当点击底部按钮时,列表中序号超过6的项目可以向下拉出或者向上收起. 用slideUp(),遇见一个问题.展开列表项会产生不正常位移,如下图所示.动画结束发生位移. 出现这个问 ...

  2. C++ 与OpenCV 学习笔记

    联合体:当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union) 1. 联合体是一种结构: 2. 他的所有成员相对于基地址的偏移量均为0: 3. 此结构空间要大到足够容纳最&qu ...

  3. 简单的C语言文法

    <程序>→<外部声明>|<程序><外部声明> <外部声明>→<函数定义>|<声明> <函数定义>→< ...

  4. title换行

  5. WebView-存在的内存泄漏

    0. Notice - earlier version 要使用WebView不造成内存泄漏,首先应该做的就是不能在xml中定义webview节点,而是在需要的时候动态生成.即:可以在使用WebView ...

  6. liniux mint android-ndk风波

    我的安装过程sudo chmod a+x android-ndk-r10d-linux-x86_64.bin/dowonload $ ./android-ndk-r10d-linux-x86_64.b ...

  7. How to see the "real" available resources ?

    Hi, Hope this will help you : nova hypervisor-stats It will return the statistics of the Hypervisor ...

  8. 使用KRPano资源分析工具强力加密KRPano项目(XML防破解,切片图保护,JS反调试)

    软件交流群:571171251(软件免费版本在群内提供) krpano技术交流群:551278936(软件免费版本在群内提供) 最新博客地址:blog.turenlong.com 限时下载地址:htt ...

  9. 在cygwin部署hadoop出现的问题:$ ./bin/hadoop version 显示错误: 找不到或无法加载主类 org.apache.hadoop.util.VersionInfo

    解决方案 找到hadoop主目录的bin文件夹下的hadoop文件,将倒数第二行 exec "$JAVA" $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS & ...

  10. Mybatis批量操作

    首先,mysql需要数据库连接配置&allowMultiQueries=true jdbc:mysql://127.0.0.1:3306/mybank?useUnicode=true& ...