(OK) 适用于WF4.0的流程设计器 (Wxd.WF,BPM.Foundation,Wxwinter.WF 升级用)
(OK) VisualWorkflowTracking aka WorkflowSimulator
http://blogs.msdn.com/b/kushals/archive/2009/12/22/visualworkflowtracking-aka-workflowsimulator.aspx
----------------------------------------------------------------------------
http://***/zh-CN/Info/catalog/14027.html
代码:http://files.cnblogs.com/zengxinle/WorkflowDesigner_4Code.zip
在WF3.0里面,就能将工作流设计器宿主到你自己的应用程序中,但是除了做一些基本的操作,做一些复杂的操作将非常的难。
在WF4.0中应用移植性变得更好,只需200行代码就能创建一个功能完全也非常有用的工作流设计器。
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,
0
);
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();