源代码下载:http://www.shareidea.net/opensource.htm
在线演示:http://www.shareidea.net/workflow.htm
视频教程: http://www.shareidea.net/video/sharedesigner/sharedesigner.html
技术支持QQ群:85444465
本文系列索引:
使用silverlight构建一个工作流设计器(一)
使用silverlight构建一个工作流设计器(二)
使用silverlight构建一个工作流设计器(三)
使用silverlight构建一个工作流设计器(四)
使用silverlight构建一个工作流设计器(五)
使用silverlight构建一个工作流设计器(六)
使用silverlight构建一个工作流设计器(七)
使用silverlight构建一个工作流设计器(八)
使用silverlight构建一个工作流设计器(九)
使用silverlight构建一个工作流设计器(十)
使用silverlight构建一个工作流设计器(十一)
本章主要实现活动和规则的淡入、淡出效果,另外讨论了xaml文件的构造方式,以及支持皮肤变换的原理。
六 增强的用户体验功能
6.6 增加动画效果
上一章我们给菜单增加了动画效果,这一章里面我们继续增加动画效果,包括:
l 新增活动的淡入效果
l 删除活动的淡出效果
l 新增规则的淡入效果
l 删除规则的淡出效果
本文源地址: http://www.cnblogs.com/chegan/archive/2009/05/13/1455307.html
6.6.1 淡入效果
这些动画的实现比较简单,首先需要增加一个DoubleAnimation对象,xaml代码如下:
Code
<Storyboard x:Name="sbDisplay">
<DoubleAnimation From="0" To="0.8" Duration="00:00:1.0"
Storyboard.TargetName=""
Storyboard.TargetProperty="Opacity" >
DoubleAnimation>
Storyboard>
TargetName 指出实现动画效果的对象。
TargetProperty 指出对象的那个属性实现动画
From 指出TargetProperty的初始值
To 指出TargetProperty的最终值
Duration 指出动画的持续时间
这些属性值也可以在后台使用c#代码来设置。在我使用的过程中,使用了
Storyboard.SetTargetName(sbDisplay, "currentPic");
来动态设置动画的TargetName值,但在运行过程中总是错误,如下图所示:
好像和命名空间有关,后来使用
Storyboard.SetTarget(sbDisplay, currentPic);
才得到正确结果,如果您对此有了解,请帮忙给出原因。
另外 TargetProperty 属性也支持用户自定义的属性,这个我们自定义动画效果提供了很大的方便,本程序中也使用了这个特性。
在活动和规则的构造函数中调用动画的开始函数,即可实现活动和规则的淡入显示效果。
sbDisplay.Begin();
6.6.2 淡出效果
和淡入效果有两点不同
l DoubleAnimation 的From和To属性和淡入效果的正好对调
l 淡出效果不能在删除规则的函数中实现,因为删除以后,就看不到对象了,所以要修改一下删除对象的函数方法。首先播放淡出动画效果,并设置动画播放完毕的事件,在完毕事件中进行对象的删除。如下所示:
Code
bool isDeleted = false;
public void Delete()
{
if (!isDeleted)
{
isDeleted = true;
sdPicture.ColseAnimationCompleted += new ColseAnimationCompletedDelegate(sdPicture_ColseAnimationCompleted);
sdPicture.ShowCloseAnimation();
}
}
void sdPicture_ColseAnimationCompleted(object sender, EventArgs e)
{
if (isDeleted)
{
if (this.BeginRuleCollections != null)
{
foreach (Rule r in this.BeginRuleCollections)
{
r.RemoveBeginActivity(this);
}
}
if (this.EndRuleCollections != null)
{
foreach (Rule r in this.EndRuleCollections)
{
r.RemoveEndActivity(this);
}
}
if (DeleteActivity != null)
DeleteActivity(this);
_container.RemoveActivity(this);
}
}
6.7 使用不同的活动对象图片
在前面的章节中,对于活动我们都使用一个矩形对象以及对这个矩形对象进行剪裁处理来表示不同类型的互动外观。这种方式代码量少,但是如果表示更复杂的对象图形就无能为力了,在这一章中,我们给不同类型的活动都使用一个用户控件来表示。根据活动的类型分为以下几种:
l 起始活动
l 终结活动
l 分支活动
l 汇聚活动
l 交互互动
l 自动活动
对于不同的活动分别有一个用户控件来表示,这样业务逻辑就比较清晰了。
题外话:xaml的构造方式
本章没有多少技术点需要说的,那么我们就来看一看silverlight的用户控件(.xaml)的运行方式。我们新建一个xaml文件SilverlightControl1.xaml,在vs.net的解决方案浏览窗口中可以看到有两个文件,SilverlightControl1.xaml以及后台代码文件SilverlightControl1.xaml.cs。
Xaml文件里面的内容是一段xaml代码,如下所示:
Code
<UserControl x:Class="Shareidea.Web.UI.Control.Workflow.Designer.SilverlightControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
Grid>
UserControl>
这个是一个标准的xaml文件,宽400高300,包含一个名称为LayoutRoot的Grid对象。
SilverlightControl1.xaml.cs文件内容如下:
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace Shareidea.Web.UI.Control.Workflow.Designer
{
public partial class SilverlightControl1 : UserControl
{
public SilverlightControl1()
{
InitializeComponent();
}
}
}
开头的命名空间包含了silverlight常用的命名空间。
需要说明的有以下几点:
l 这个类使用了partial(部分类)的方式声明
l 另一个需要注意的是,构造函数内的InitializeComponent,我们使用vs.net的追踪到这个函数的实现,可以在vs.net中打开一个新的文件,文件名称为SilverlightControl1.g.cs.他的代码如下所示:
Code
#pragma checksum "D:\webapp\AutoForm\workflow\ShareDesigner\ShareDesigner\SilverlightControl1.xaml" "{406ea660-64cf-4c82-b6f0-42d48172a799}" "4F852CC5E0AFC0A2BA980AB6BBB4D9E6"
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
// Runtime Version:2.0.50727.3053
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
using System;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Resources;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace Shareidea.Web.UI.Control.Workflow.Designer {
public partial class SilverlightControl1 : System.Windows.Controls.UserControl {
internal System.Windows.Controls.Grid LayoutRoot;
private bool _contentLoaded;
///
/// InitializeComponent
///
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public void InitializeComponent() {
if (_contentLoaded) {
return;
}
_contentLoaded = true;
System.Windows.Application.LoadComponent(this, new System.Uri("/ShareDesigner;component/SilverlightControl1.xaml", System.UriKind.Relative));
this.LayoutRoot = ((System.Windows.Controls.Grid)(this.FindName("LayoutRoot")));
}
}
}
可以看出,这个是vs.net自动生成的代码,这个类的声明方式和类名称都和我们的SilverlightControl1.cs相同,也就是说,这两个文件在系统编译时将生成同一个类。我们特别注意一下InitializeComponent函数内的代码。
System.Windows.Application.LoadComponent(this, new System.Uri("/ShareDesigner;component/SilverlightControl1.xaml", System.UriKind.Relative));
这行代码表示根据指定的文件定位符动态载入一个xaml文件,并将生成的对象赋给xaml文件的根元素(在本例中是一个UserControl)。第二行代码
this.LayoutRoot = ((System.Windows.Controls.Grid)(this.FindName("LayoutRoot")));
表示从xmal生成的用户控件中找到名称为LayoutRoot的的Grid对象,并赋给类的内部变量LayoutRoot。正是这一段代码,我们才可以在SilverlightControl1.cs中直接使用LayoutRoot这个变量名称,并且这个变量指向xmal文件中的名称为LayoutRoot的Grid对象。
如果您熟悉asp.net forums(国外的一个开源的论坛),那么这种方式您一定很熟悉了,在asp.net froums中大量使用了这种技术来支持更换皮肤,现在我们了解了xaml的构造方式,也可以使用这种技术写出支持变换皮肤的silverlight程序了。
变化皮肤技术经常出现在一些程序中,但实现方式原理有几种。其中一种是通过css来实现皮肤改变,但这种方式有一定的局限性。上文中分析的皮肤变换技术比css的实现要好一点。在下面的章节中,将使用这种技术。