`

坚持学习WF(5):自定义活动(CustomActivity)

阅读更多

当WF提供的标准活动不能满足我们的需求的时候,我们就需要定义自己的活动。工作流引擎并不会区别一个活动是WF提供的标准活动还是第三方自定义活动.自定义活动有两种方式,组合方式和继承方式.组合是你从工具箱里拖出你需要的活动将他们组织在一起形成一个新的活动;使用继承的方式我们需要编写一个类,该类可以继承Activity类或其他的类,比如SequenceActivity等.组合的方式比较简单,下面我们就使用继承的方式来自定义一个活动。


实现逻辑
 

我现在要完成一个这样的活动,我去银行存钱,当我存钱的时候会有一个友情提示,提示我保护好您的密码,然后如果存钱的数额小于1000就提示说钱太少,不能存,如果大于1000就提示存款成功.

下面我们就新建一个Activity名字叫CreditActivity,我们在它的属性里将Base类设置为Activity,这个基类已经足够了,然后我们增加一个依赖属性AccountProperty来表示存款数额,代码如下:

public static DependencyProperty AccountProperty  = System.Workflow.ComponentModel.DependencyProperty.Register( 
           
"Account"typeof(Int32), typeof(CreditActivity)); 
      
 [Description("存款数额")] 
       [Category(
"自定义活动示例")] 
       [Browsable(
true)] 
       [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 
       
public Int32 Account 
       { 
           
get 
           { 
               
return ((Int32)(base.GetValue( 
                   CreditActivity.AccountProperty))); 
           } 
           
set 
           { 
               
base.SetValue(CreditActivity.AccountProperty, value); 
           } 
       }

然后在增加一个依赖事件BeCarefulEvent ,用于当用户存钱的提示它注意保护密码,代码如下:

public static DependencyProperty BeCarefulEvent = DependencyProperty.Register("BeCareful"typeof(EventHandler<CustomActivityEventArgs>), typeof(CreditActivity)); 
       [DescriptionAttribute(
"友情提示:注意保护密码")] 
       [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 
       [BrowsableAttribute(
true)] 
       [Category(
"Handlers")] 
       
public event EventHandler<CustomActivityEventArgs> BeCareful 
       { 
           add 
           { 
               
base.AddHandler(CreditActivity.BeCarefulEvent, value); 
           } 
           remove 
           { 
               
base.RemoveHandler(CreditActivity.BeCarefulEvent, value); 
           } 
       }

然后我们要实现我们的逻辑代码,我们需要重写Activity类的Execute方法,并在该方法中引发BeCarefulEvent事件。这个方法返回一个ActivityExecutionStatus,代表当前Activity实例的运行状态的枚举值,Return.base.Execute(executionContext)这个默认的返回ActivityExecutionStatus.Closed. ActivityExecutionContext是提供活动运行环境的相关信息.代码如下

protected override ActivityExecutionStatus Execute( ActivityExecutionContext executionContext) 
        { 
            CustomActivityEventArgs customActivityEventArgs 
= new CustomActivityEventArgs(this.Description); 
            
this.RaiseGenericEvent<CustomActivityEventArgs>(BeCarefulEvent, this, customActivityEventArgs); 
            
//simulate an account lookup 
            if (Account <= 1000
            { 
                Console.WriteLine(
"钱也太少了吧,要大于1000的"); 
            } 
            
else 
            { 
                Console.WriteLine(
"存好了,下回多存点啊"); 
            } 

            
return base.Execute(executionContext); 
        }

下面我就在Workflow中设置它的存款数额为600,和BeCarefulEvent事件,如下图:

3

(图 一)

BeCarefulEvent的事件处理程序onBeCareful的代码如下:

private void onBeCareful(object sender, CaryActivityLibrary.CustomActivityEventArgs e) 
        { 
            Console.WriteLine(e.ActivityDescription
+":小心保护密码");
            Console.WriteLine()
         }

现在我们来运行我们的程序:

4


提高设计体验

上面我们只是简单的实现我们的逻辑,但很多时候并不是逻辑是最重要的,我们的设计体验同样重要,下面我们说说自定义活动中怎样才能提高设计的体验。


自定义活动图标

不知道你注意到没有,在(图一)中的我们自定义的活动前的图标很好看,这个也是我自己选的,只要下面的一行代码就可以实现:

[ToolboxBitmap(typeof(CreditActivity), "Test.png")] 
public partial class CreditActivity : System.Workflow.ComponentModel.Activity{..}

注意图片的生成操作属性应该设置为“嵌入的资源”,如下图:

5


自定义活动主题

(图一)中活动的主题的样式也是我们自己可以定制的,我们新建一个CreditActivityTheme类,继承自ActivityDesignerTheme,在其构造函数中设置我们想要的样式,代码如下:

public class CreditActivityTheme : ActivityDesignerTheme 
    { 
        
public CreditActivityTheme(WorkflowTheme theme) 
            : 
base(theme) 
        { 
            
this.BackColorStart = Color.LightSteelBlue; 
            
this.BackColorEnd = Color.Gainsboro; 
            
this.BorderStyle = DashStyle.DashDot; 
            
this.BorderColor = Color.DarkRed; 
            
this.BackgroundStyle = LinearGradientMode.ForwardDiagonal;            
        } 
    }

其实Visual Studio本身也提供了强大的主题设计器。


自定义活动行为

我们不但可以设置样式,还可以增加以下的行为来用另一种方式设置我们的存款数额,如下图:

6

要实现上面的并不难,你需要定义一个CreditActivityDesigner类继承自ActivityDesigner,代码如下:

[ActivityDesignerTheme(typeof(CreditActivityTheme))] 
    
public class CreditActivityDesigner : ActivityDesigner 
    { 
        
protected override System.Collections.ObjectModel.ReadOnlyCollection<DesignerAction> DesignerActions 
        { 
            
get 
            { 
                List
<DesignerAction> list = new List<DesignerAction>(); 
                
foreach (DesignerAction temp in base.DesignerActions) 
                { 
                    list.Add(
new DesignerAction(this, temp.ActionId, temp.Text)); 
                } 
                
return list.AsReadOnly(); 
            } 
        } 

        
protected override ActivityDesignerVerbCollection Verbs 
        { 
            
get 
            { 
                ActivityDesignerVerbCollection NewVerbs 
= new ActivityDesignerVerbCollection(); 
                NewVerbs.AddRange(
base.Verbs); 
                ActivityDesignerVerb menu 
= new ActivityDesignerVerb(this, DesignerVerbGroup.View, "设置存款数额啦"new EventHandler(menu_click)); 
                NewVerbs.Add(menu); 
                
return NewVerbs; 
            } 
        } 
 
        private void menu_click(object sender, EventArgs e) 
        { 
            
using (CreditActivitySet wf = new CreditActivitySet()) 
            { 
                
int v = (int)this.Activity.GetValue(CreditActivity.AccountProperty); 
                wf.Value 
= v.ToString(); 
                wf.ShowDialog(); 
                
this.Activity.SetValue(CreditActivity.AccountProperty, Convert.ToInt32(wf.Value)); 
            } 
        } 
    }

CreditActivitySet 是设置数额的window form。


自定义活动验证器

你可能还会记得当你拖动一个CodeActivity的时候,如果你没有设置它的ExecuteCode属性,它会有一个叹号,编译不能通过。下面我们也来实现同样的效果,如果我们没有设置存款数额Account,我们就也出现类似的提示,我们定义一个CreditActivityValidator类继承自ActivityValidator。代码如下:

public class CreditActivityValidator : ActivityValidator 
    { 
        
public override ValidationErrorCollection Validate( 
            ValidationManager vManager, 
object obj) 
        { 
            ValidationErrorCollection errors 
= base.Validate(vManager, obj); 
            
if (obj is CreditActivity) 
            { 
                CreditActivity creditActivity 
= obj as CreditActivity; 
                
if (creditActivity.Parent != null
                { 
                    
if (creditActivity.Account == 0
                    { 
                        errors.Add( 
                            ValidationError.GetNotSetValidationError( 
                                
"Account")); 
                    } 
                } 
            } 
            
return errors; 
        } 
    }

效果如下图:

7

我们是通过以下特性来应用到我们自定义的活动上的 : 

 [ActivityValidator(typeof(CreditActivityValidator))] 
    [Designer(
typeof(CreditActivityDesigner))] 
    
public partial class CreditActivity : System.Workflow.ComponentModel.Activity    {}


定制工具箱行为

我们还可以定制工具箱行为,就是当我们把一个活动从工具箱拖到工作流设计器上时所做的动作,我另外定义了一个CaryCompositeActivity 活动,继承自 SequenceActivity,这样就可以包含子活动了,当我们把CaryCompositeActivity 拖到工作流设计器时,我们给他添加一些默认的子活动,我们编写了一个CaryCompositeActivityToolboxItem 并继承自ActivityToolboxItem,代码如下:

[Serializable] 
   
public class CaryCompositeActivityToolboxItem : ActivityToolboxItem 
   { 
      
 public CaryCompositeActivityToolboxItem() 
           : 
base() 
       {    } 
       public CaryCompositeActivityToolboxItem( 
           SerializationInfo info, StreamingContext context) 
               : 
base(info, context) 
       { } 
       
protected override IComponent[] CreateComponentsCore(IDesignerHost host) 
       { 
           
CaryCompositeActivity activity = new CaryCompositeActivity(); 
           
IfElseActivity ifElse = new IfElseActivity("ifElse1"); 
           
ifElse.Activities.Add(new IfElseBranchActivity("ifFirstCondition")); 
           ifElse.Activities.Add(
new IfElseBranchActivity("ifSecondCondition")); 
           ifElse.Activities.Add(
new IfElseBranchActivity("elseBranch")); 
           activity.Activities.Add(ifElse); 
           
return new IComponent[] { activity }; 
       } 
   }

然后我们在写一个类来实现该活动只能添加指定的子活动,我们编写一个类CaryCompositeActivityDesigner 继承自SequentialActivityDesigner,代码如下:

public class CaryCompositeActivityDesigner : SequentialActivityDesigner 
    { 
        
private static List<Type> allowedActivityTypes = new List<Type>(); 
        
static CaryCompositeActivityDesigner() 
        { 
            
allowedActivityTypes.Add(typeof(IfElseActivity)); 
            allowedActivityTypes.Add(
typeof(IfElseBranchActivity)); 
            allowedActivityTypes.Add(
typeof(CodeActivity)); 
        } 
        
public override bool CanInsertActivities(HitTestInfo insertLocation, 
            ReadOnlyCollection
<Activity> activitiesToInsert) 
        { 
            
Boolean result = true
            
if (activitiesToInsert != null
            { 
                
foreach (Activity activity in activitiesToInsert) 
                { 
                    result 
= (allowedActivityTypes.Contains(activity.GetType())); 
                    
if (result == false
                    { 
                        
break
                    } 
                } 
            } 
            
return result; 
        } 
    }


效果如下图:

8

allowedActivityTypes 集合中我们指定了只能添加 IfElseActivity,IfElseBranchActivity,CodeActivity三种活动,但是在它的子活动IfElseBranchActivity中就没有这个限制了,因为IfElseBranchActivity也有自己的设计器。

代码下载:CaryActivity
上一篇:坚持学习WF(4):活动(Activity)和依赖属性(DependencyProperty)
下一篇:坚持学习WF(6):开发可复用的宿主程序

分享到:
评论

相关推荐

    坚持学习WF(5):自定义活动(CustomActivity) 源码

    在Windows Workflow Foundation (WF)中,自定义活动(CustomActivity)是开发人员根据特定业务需求创建的自定义工作流组件。本篇文章将深入探讨如何利用C#编程语言创建自定义活动,并通过源码分析来理解其工作原理。...

    WF教程_坚持学习WF

    坚持学习WF(5):自定义活动(CustomActivity) 4.5两篇对主要对活动(Actibity)的介绍和依赖属性(DependencyObject)和DependencyProperty事件的使用。 坚持学习WF(6):开发可复用的宿主程序 主要实现两个类来对...

    Windows Workflow Foundation开发实战系列课程(5):自定义活动开发

    在这个“Windows Workflow Foundation开发实战系列课程(5):自定义活动开发”中,我们将深入探讨如何利用WF创建自定义活动,以满足特定业务需求。 1. 自定义活动概述: 自定义活动是WF的核心组成部分,它是工作流...

    坚持学习WF,WF学习教程

    坚持学习WF(5):自定义活动(CustomActivity) 4.5两篇对主要对活动(Actibity)的介绍和依赖属性(DependencyObject)和DependencyProperty事件的使用。 坚持学习WF(6):开发可复用的宿主程序 主要实现两个类来对...

    WF4 自定义容器活动

    自定义容器活动是在WF4中创建自己的复合活动,可以包含其他活动,类似于在流程图中使用一个形状来封装多个子步骤。下面我们将深入探讨如何实现WF4自定义容器活动,并在自定义活动中添加其他活动。 一、理解WF4...

    坚持学习WF

    坚持学习WF(4):活动(Activity)和依赖属性(DependencyProperty) 坚持学习WF(5):自定义活动(CustomActivity) 4.5两篇对主要对活动(Actibity)的介绍和依赖属性(DependencyObject)和DependencyProperty事件的使用。...

    WF从入门到精通(第十三章):打造自定义活动(一)源码

    通过研究这些代码,读者可以更好地理解如何将理论知识应用到实践中,学习如何创建、调试和优化自定义活动。 总的来说,掌握WF中的自定义活动开发是提升WF应用水平的关键。通过实践,开发者不仅能理解WF的工作原理,...

    自定义活动(CustomActivity)

    在Windows Workflow Foundation (WF)中,自定义活动是扩展WF功能的关键途径,允许开发者根据具体需求构建定制化的工作流程步骤。当我们发现WF提供的内置活动不足以满足业务逻辑时,可以通过两种方式创建自定义活动:...

    坚持学习WF(1):从HelloWorld开始 源码

    在本篇“坚持学习WF(1):从HelloWorld开始”的源码分析中,我们将深入理解WF的基础知识和创建第一个工作流的步骤。 首先,让我们了解WF的基本概念。WF提供了一种模型化业务流程的方式,通过活动(Activities)来表示...

    wf工作流资料<转自网上的笔记>

    "坚持学习WF(5)自定义活动(CustomActivity)"揭示了WF的灵活性,说明如何创建自己的活动以满足特定业务需求。自定义活动是WF强大的一点,它允许开发者扩展WF库,实现复杂逻辑。 "坚持学习WF(6)开发可复用的宿主程序...

    workflow 自定义控件

    在.NET Framework中,我们可以使用Windows Workflow Foundation (WF) 来创建自定义活动。 2. **创建自定义活动类**: 在C#或VB.NET中,我们需要创建一个继承自`System.Activities.Activity`或其子类的类。这个类将...

    WorkFlow HOL实验 WF HOL(2) 创建自定义活动

    ### WorkFlow HOL实验 WF HOL(2) 创建自定义活动 #### 概述 在本章节中,我们将继续探讨WorkFlow HOL实验系列中的第二部分:创建自定义活动(Creating Custom Activities)。这一节的重点在于如何利用Visual ...

    FDASFDASFDASFDAS

    AFDSAFDAS验收报告验收报告验收报告验收报告验收报告验收报告

    工作流WF4.0入门(八)

    在本文中,我们将深入探讨WF4.0的自定义活动和跟踪技术,这是开发高效、灵活的工作流解决方案的关键组成部分。 首先,让我们了解WF4.0的基本概念。WF4.0全称为Windows Workflow Foundation 4.0,它提供了一个平台,...

    WF40 实战:实现自动访问网站机器人.doc

    5. 自定义活动:VisitPage 活动 VisitPage 活动是 WF4.0 中的一个自定义活动,可以用来访问指定的网页。该活动有两个属性:Url 和 WaitTime,分别表示访问的网页 URL 和等待时间。 6. 自定义活动:InputData 活动 ...

    Microsoft WF 活动实例

    **Microsoft WF 活动实例详解** ...通过理解WF的基本概念、内置活动以及如何创建自定义活动,你可以开始构建自己的工作流解决方案。结合提供的实例教程,逐步实践,相信你很快就能掌握WF的核心技能。

    Apress - Beginning WF: Windows Workflow in .NET 4.0 Mar 2010

    - **创建工作流扩展和自定义活动**:教授如何开发自定义的工作流活动和扩展,以满足特定业务需求。 - **构建支持长时间运行的工作流的应用程序**:讲解如何处理长时间运行的工作流,并确保其高效稳定地执行。 - **在...

    WF 4.0 and Activity Designer tidbits

    Activity Designer是WF 4.0中的一种可视化设计工具,用于创建和自定义工作流活动。 在"WF 4.0 and Activity Designer tidbits"的主题下,我们主要探讨的是如何利用WF 4.0的特性以及Activity Designer来提高工作效率...

    WF从入门到精通(第七章):基本活动的操作源码

    除了使用内置的基本活动外,WF还允许开发者创建自定义活动,以满足特定的业务需求。通过查看和分析提供的源码,你可以学习如何扩展WF,定义自己的活动类,并集成到工作流程中。 5. **活动设计与执行** 学习如何在...

    PTC_WF5_CORRECTOR

    PTC_WF5_CORRECTOR 是一个专门针对PTC(Parametric Technology Corporation)Windchill WF5(Workflow Foundation 5)系统的修复工具。Windchill是PTC提供的一款企业级的产品生命周期管理(PLM)软件,它涵盖了产品...

Global site tag (gtag.js) - Google Analytics