WF4.0工作流设计器

代码:/Files/zhuqil/2543.CustomWorkflowDesigner_47FBA3A3.zip

    在WF3.0里面,就能将工作流设计器宿主到你自己的应用程序中,但是除了做一些基本的操作,做一些复杂的操作将非常的难。
    在WF4.0中应用移植性变得更好,只需200行代码就能创建一个功能完全也非常有用的工作流设计器。

WF4.0工作流设计器_第1张图片

WorkflowDesigner

    WorkflowDesigner是工作流设计器运行的主类。它通过View属性给出了实际的设计界面。通过PropertyInspectorView属性给出了相关属性。如果宿主在WPF中,这两个属性准备给WPF UIElement使用,很容易将他们添加到表单上。加载和保存一个工作流也非常容易,需要Load() 和 Save()函数,它们需要使用一个XAML文件做参数。部分代码如下:

代码
_workflowDesigner  =   new  WorkflowDesigner();

_workflowDesigner.Load(_fileName);

var view 
=  _workflowDesigner.View;

Grid.SetColumn(view, 
1 );

Grid.SetRow(view, 
1 );

LayoutGrid.Children.Add(view);

var propInspector 
=  _workflowDesigner.PropertyInspectorView;

Grid.SetColumn(propInspector, 
2 );

Grid.SetRow(propInspector, 
1 );

LayoutGrid.Children.Add(propInspector);

DesignerMetadata:
    另外一件需要做的事情是注册流程活动设计的metadata;它只是一个简单的调用,但是如果舍弃它,就意味着所有活动都只是一个收起的小图像,也不可能扩展。

new  DesignerMetadata().Register();

 将Activity显示在工具栏上

    左边的工具栏使用另外一个标准的WPF控件:ToolboxControl。它也非常容易添加到WPF的表单上面。将Activity的类型添加ToolboxItemWrapper。这样,不需要做其它工作,就能将Activity直接拖放到设计界面上。在下面的代码只是通过扫描几个程序集得到所有Activity类型,如果它是有效的Activity,我们就将它添加到工具栏上。

代码

var toolbox 
=   new  ToolboxControl();

var cat 
=   new  ToolboxCategory( " Standard Activities " );

var assemblies 
=   new  List < Assembly > ();

assemblies.Add(
typeof (Send).Assembly);

assemblies.Add(
typeof (Delay).Assembly);

assemblies.Add(
typeof (ReceiveAndSendReplyFactory).Assembly);

var query 
=  from asm  in  assemblies

            from type 
in  asm.GetTypes()

            
where  type.IsPublic  &&

            
! type.IsNested  &&

            
! type.IsAbstract  &&

            
! type.ContainsGenericParameters  &&

            (
typeof (Activity).IsAssignableFrom(type)  ||

            
typeof (IActivityTemplateFactory).IsAssignableFrom(type))

            orderby type.Name

            select 
new  ToolboxItemWrapper(type);

query.ToList().ForEach(ti 
=>  cat.Add(ti));

toolbox.Categories.Add(cat);

Grid.SetColumn(toolbox, 
);

Grid.SetRow(toolbox, 
1 );

LayoutGrid.Children.Add(toolbox);

 当前的selection
    在表单的顶部,我显示当前选择的activity和它的父Activity。WorkflowDesigner有一个项目集合,里面有一组有用的对象。其中有一个就是Selection 对象,我们可以周期性地检查此Selection,使用Subscribe()函数和在一个handler中传递,当selection改变的时候就会触发,这样可能更容易实现。

_workflowDesigner.Context.Items.Subscribe < Selection > (SelectionChanged);

 Handler一样也不复杂:

代码

private void SelectionChanged(Selection selection)

{

    var modelItem = selection.PrimarySelection;

    var sb = new StringBuilder();

 

    while (modelItem != null)

    {

        var displayName = modelItem.Properties["DisplayName"];

 

        if (displayName != null)

        {

            if (sb.Length > 0)

                sb.Insert(0, " - ");

            sb.Insert(0, displayName.ComputedValue);

        }

 

        modelItem = modelItem.Parent;

    }

 

    CurrentActivityName.Text = sb.ToString();

}


验证workflow
    让用户知道设计的工作流是否有效是非常完美的事情。这也非常简单,在WorkflowDesigner services中添加一个IValidationErrorService。在这个例子中,我在表单上添加一个listbox。让IValidationErrorService将每项错误添加到ListBox项中。不需要去调用任何函数,一旦工作流有改变,IValidationErrorService会被自动的调用。

var validationErrorService  =   new  ValidationErrorService(WorkflowErrors.Items);

_workflowDesigner.Context.Services.Publish
< IValidationErrorService > (validationErrorService);

     IValidationErrorService由一个简单的函数组成。将错误写在一个参数列表中。

代码
public   class  ValidationErrorService : IValidationErrorService

{

    
private  IList _errorList;

    
public  ValidationErrorService(IList errorList)

    {

        _errorList 
=  errorList;

    }

 

    
public   void  ShowValidationErrors(IList < ValidationErrorInfo >  errors)

    {

        _errorList.Clear();

        
foreach  (var error  in  errors)

        {

            _errorList.Add(error.Message);

        }

    }

}

运行workflow:

    为了运行工作流,我添加一些代码,使用WorkflowApplication来运行工作流。加载也非常容易,ActivityXamlServices.Load()需要传递一个文件来调用。它会返回一个DynamicActivity。

代码
var writer  =   new  StringWriter();

var workflow 
=  ActivityXamlServices.Load(_fileName);

var wa 
=   new  WorkflowApplication(workflow);

wa.Extensions.Add(writer);

wa.Completed 
=  WorkflowCompleted;

wa.OnUnhandledException 
=  WorkflowUnhandledException;

wa.Run();
原文; http://msmvps.com/blogs/theproblemsolver/archive/2009/12/23/rehosting-the-workflow-designer-in-wf4.aspx
原文链接: http://www.cnblogs.com/zhuqil/archive/2010/01/13/Workflow-Designer.html

你可能感兴趣的:(WF4.0工作流设计器)