偶发现微软的WF4.0论坛也是一个学习WF4.0的好地方,打算把一些典型的问题和答案整理出来,方便大家查阅和学习,先整理几个出来,以后我会持续更新的,WF4.0论坛的地址是:http://social.msdn.microsoft.com/Forums/zh-CN/wfprerelease/threads。
1、Q:获取自定义活动的子活动:
A:实现的代码
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
{
Activity act = new Workflow1();
ShowChildren(act);
}
static void ShowChildren(Activity act, int level = 0 )
{
foreach (var a in WorkflowInspectionServices.GetActivities(act))
{
Console.WriteLine( " {0}{1} ({2}) " , new string ( ' . ' , level * 3 ), a.DisplayName, a.GetType().Name);
ShowChildren(a, level + 1 );
}
}
2、Q:在宿主设计器中,通过编程的方式在Flowchar添加arguments :
A:实现的代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
ActivityBuilder builder = new ActivityBuilder();
builder.Implementation = new Flowchart();
designer.Load(builder);
Grid.SetColumn(designer.View, 1 );
Grid.SetRow(designer.View, 0 );
rehostGrid.Children.Add(designer.View);
DynamicActivityProperty property = new DynamicActivityProperty()
{
Name = " test " ,
Type = typeof (InArgument < string > ),
};
designer.Context.Services.GetService < ModelService > ().Root.Properties[ " Properties " ].Collection.Add(property);
3、Q:如何将代码方式工作流转化为Xaml格式的工作流。
A:实现的代码,这个不支持lambda,先将其转换为VBRefrenceValue等:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
ab1.Name = " convert " ;
ab1.Implementation = GetServiceWorkflow();
StringBuilder sb = new StringBuilder();
StringWriter tw = new StringWriter(sb);
XamlWriter xw = ActivityXamlServices.CreateBuilderWriter( new XamlXmlWriter(tw, new XamlSchemaContext()));
XamlServices.Save(xw, ab1);
Console.WriteLine(sb.ToString());
4、Q:IActivityTemplateFactory能否用在变量上
A:可以,一个变量情况:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
{
public Activity Create(System.Windows.DependencyObject target)
{
var stringVar = new Variable < string > () { Name = " stringVar " , Default = " Hello World " };
return new Sequence
{
Variables = { stringVar },
Activities =
{
new WriteLine
{
Text = new VisualBasicValue < string > ( " stringVar " )
}
}
};
}
}
多个变量的情况:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
{
public Activity Create(System.Windows.DependencyObject target)
{
var stringVar = new Variable < string > () { Name = " stringVar " , Default = " Hello World " };
var stringVar2 = new Variable < string > () { Name = " stringVar2 " , Default = " Good bye World " };
var stringVar3 = new Variable < string > () { Name = " stringVar3 " , Default = " Another var " };
return new Sequence
{
Variables = { stringVar, stringVar2, stringVar3 },
Activities =
{
// Add your activites here...
}
};
}
}
5、Q:怎样在dll中找出WF的活动:
A:实现的代码
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
where typeof (System.Activities.Activity).IsAssignableFrom(t) ||
typeof (System.Activities.Presentation.IActivityTemplateFactory).IsAssignableFrom(t)
select t.FullName;
6、Q:在宿主设计器上隐藏Arguments按钮:
A:实现的代码
ShellBarItemVisibility 枚举有如下值:None, Variables ,Arguments, Imports ,Zoom ,MiniMap , All。
7、Q:宿主设计器中,如何由string来创建flowchar
A:实现的代码
wd.Load(XamlServices.Load( new StringReader(s)));
8、Q:在设计时动态添加Argument到自定义动中:
A:实现的代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
[Designer( typeof (TAGLIST_SetPropertyDesigner))]
public sealed class TAGLIST_SetProperty : Extended_Sequence
{
[CategoryAttribute( " Input/Output " )]
public InOutArgument < TAGLIST > Taglist { get ; set ; }
private Collection < Argument > parameters;
[Editor( typeof (ArgumentCollectionPropertyEditor), typeof (DialogPropertyValueEditor))]
public Collection < Argument > Parameters
{
get
{
if ( this .parameters == null )
{
this .parameters = new Collection < Argument > ();
}
return this .parameters;
}
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{ < br /> base .CacheMetadata(metadata);
Collection < RuntimeArgument > arguments = new Collection < RuntimeArgument > ();
for ( int k = 0 ; k < this .Parameters.Count; k ++ )
{
RuntimeArgument argument3 = new RuntimeArgument( " Argument " + k, this .Parameters[k].ArgumentType, this .Parameters[k].Direction, true );
metadata.Bind( this .Parameters[k], argument3);
arguments.Add(argument3);
metadata.AddArgument(argument3);
}
// metadata.SetArgumentsCollection(arguments);
}
protected override void Execute(NativeActivityContext context)
{
TAGLIST tl = Taglist.Get(context);
foreach (Argument arg in this .parameters)
{
object inp = arg.Get(context); // Throws the exception
if (inp != null && inp.GetType() == typeof (TAG))
{
TAG tag = (TAG)inp;
tl.SetProperty(tag.Key, tag.Value);
}
}
Taglist.Set(context, tl);
}
}
9、Q: 自定义活动的属性设置为一个对话框
A:实现的代码
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
static SimpleCodeActivity()
{
AttributeTableBuilder builder = new AttributeTableBuilder();
builder.AddCustomAttributes( typeof (SimpleCodeActivity), " FileName " , new EditorAttribute( typeof (FilePickerEditor), typeof (DialogPropertyValueEditor)));
MetadataStore.AddAttributeTable(builder.CreateTable());
}
FilePickerEditor:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
{
public FilePickerEditor()
{
this .InlineEditorTemplate = new DataTemplate();
FrameworkElementFactory stack = new FrameworkElementFactory( typeof (StackPanel));
stack.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
FrameworkElementFactory label = new FrameworkElementFactory( typeof (Label));
Binding labelBinding = new Binding( " Value " );
label.SetValue(Label.ContentProperty, labelBinding);
label.SetValue(Label.MaxWidthProperty, 90.0 );
stack.AppendChild(label);
FrameworkElementFactory editModeSwitch = new FrameworkElementFactory( typeof (EditModeSwitchButton));
editModeSwitch.SetValue(EditModeSwitchButton.TargetEditModeProperty, PropertyContainerEditMode.Dialog);
stack.AppendChild(editModeSwitch);
this .InlineEditorTemplate.VisualTree = stack;
}
public override void ShowDialog(PropertyValue propertyValue, IInputElement commandSource)
{
Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
if (ofd.ShowDialog() == true )
{
propertyValue.Value = ofd.FileName.Substring(o fd.FileName.LastIndexOf( ' \\ ' ) + 1 );
}
}
}
DataTemplate:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:pres ="clr-namespace:System.Activities.Presentation.PropertyEditing;assembly=System.Activities.Presentation"
x:Class ="Microsoft.Samples.Activities.Designer.PropertyGridExtensibility.EditorResources" >
< DataTemplate x:Key ="FilePickerTemplate" >
< StackPanel Orientation ="Horizontal" >
< Label Content =" {Binding Path=Value} " MaxWidth ="80" >
< Label.ToolTip >
< TextBlock Text =" {Binding Path=Value} " />
</ Label.ToolTip >
</ Label >
< pres:EditModeSwitchButton TargetEditMode =" {x:Static pres:PropertyContainerEditMode.Dialog} " />
</ StackPanel >
</ DataTemplate >
</ ResourceDictionary >
10、Q:ToolboxControl :Auto Expand/Collapse
A:实现的代码
{
Setters = {
new Setter(TreeViewItem.IsExpandedProperty, false )
}
};
11、Q:如何在宿主设计器上直接打开活动:
A:实现的代码:
XAML部分:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
Title ="MainWindow" Height ="350" Width ="525" >
< Grid Name ="Foo" >
< Grid.ColumnDefinitions >
< ColumnDefinition Width ="*" />
< ColumnDefinition Width ="3*" />
</ Grid.ColumnDefinitions >
< Button Grid.Column ="0" Click ="Button_Click" > Click Me </ Button >
</ Grid >
</ Window >
CS部分:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
using System.Activities.Core.Presentation;
using System.Activities.Presentation;
using System.Activities.Presentation.Model;
using System.Activities.Presentation.Services;
using System.Activities.Presentation.View;
using System.Activities.Statements;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication15
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
WorkflowDesigner wd;
public MainWindow()
{
InitializeComponent();
// register metadata
( new DesignerMetadata()).Register();
// create the workflow designer
wd = new WorkflowDesigner();
wd.Load( new Sequence
{
Activities =
{
new Sequence
{
Activities =
{
new ForEach < string >
{
Body = new ActivityAction < string >
{
Argument = new DelegateInArgument < string > { Name = " foo " },
Handler =
new Sequence
{
Activities =
{
new If()
{
Else = new WriteLine(),
Then = new WriteLine()
}
}
}
}
}
}
}
}
});
Grid.SetColumn(wd.View, 1 );
Foo.Children.Add(wd.View);
}
private void Button_Click( object sender, RoutedEventArgs e)
{
ModelService modelService = wd.Context.Services.GetService < ModelService > ();
IEnumerable < ModelItem > activityCollection = modelService.Find(modelService.Root, typeof (Activity));
Selection.Select(wd.Context, activityCollection.ElementAt( 5 ));
}
}
}
12、Q:WorkflowApplication加载持久化的工作流:
A:实现的代码:
application.InstanceStore = new SqlWorkflowInstanceStore(...);
application.Load(id);
application.ResumeBookmark(...);
13、Q:WF4.0活动的表达式编辑器使用的语言是什么?
A:VB
14、Q:将 xaml工作流转换成C#工作流:
A:参考:http://blogs.msdn.com/mwinkle/archive/2009/06/10/types-metatypes-and-bears-oh-my.aspx
15、Q:如何在设计器上验证当前选择和拖拽的活动
A:WF4.0验证框架包含三个辅助活动,它帮助您验证WF有关的活动。这些辅助活动是GetParentChain,GetChilSubtree和GetWorkflowTree,
他们是在Constraints里面,就像你将使用AssertValidation。下面是一个代码片段:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
{
Variable < ActivityCity > element = new Variable < ActivityCity > ();
Variable < ValidationContext > context = new Variable < ValidationContext > ();
Variable < bool > result = new Variable < bool > ();
Variable < WorkflowElement > parent = new Variable < WorkflowElement > ();
return new Constraint < ActivityCity >
{
Body = new ActivityAction < ActivityCity,ValidationContext >
{
Argument1 = element,
Argument2 = context,
Handler = new Sequence
{
Variables =
{
result
},
Activities =
{
new ForEach < WorkflowElement >
{
Values = new GetParentChain
{
ValidationContext = context
},
Body = new ActivityAction < WorkflowElement >
{
Argument = parent,
Handler = new If()
{
Condition = new InArgument < bool > ((env) => object .Equals(parent.Get(env).GetType(), typeof (ActivityCountry))),
Then = new Assign < bool >
{
Value = true ,
To = result
}
}
}
},
new AssertValidation
{
Assertion = new InArgument < bool > (result),
Message = new InArgument < string > ( " ActivityCity has to be inside an ActivityCountry " ),
ErrorCode = new InArgument < string > ( " Build-1002 " ),
PropertyName = new InArgument < string > ((env) => element.Get(env).name)
}
}
}
}
};
}
16、Q:如何在WF4.0表达式编辑器上使用Generic List, Hash table, Array
A:您将需要使用VB的对象和集合初始化语法
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
New List( Of String ) From { " hello " , " world " }
New Dictionary( Of String , Object ) From { { " hello " , 42 }, { " world " , new ApplicationException() } }
17、Q:获取Flow switch表达式字符串
A:实现代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
WorkflowViewElement element = item.View as WorkflowViewElement;
if (element.Content != null )
{
Label lab = new Label();
lab.Content = item.Properties[ " Expression " ].ComputedValue.ToString();
Grid grid = element.Content as Grid;
grid.Children.Add(lab);
}
}
18、Q:在C#中通过Default值动态创建变量。
A:如果name为:zhu ,lastname为qilin,New Class1().name + New Class1().lastName求出的值为"zhuqilin",直接看代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
string ns = typeof (Class1).Namespace;
VisualBasicSettings vbSettings = new VisualBasicSettings();
vbSettings.ImportReferences.Add( new VisualBasicImportReference
{
Assembly = assemblyname,
Import = ns,
});
Sequence wf = new Sequence
{
Variables =
{
new Variable < string > {Name = " n2 " , Default = new VisualBasicValue < string > ( " New Class1().name + New Class1().lastName " )}
},
Activities =
{
new WriteLine { Text = new VisualBasicValue < string > ( " n2 " )},
}
};
VisualBasic.SetSettings(wf, vbSettings);
WorkflowInvoker.Invoke(wf);
Console.Read();
19、Q:宿主工作流设计器中验证ActivityBuilder
A:代码如下:
Activity a = ActivityXamlServices.Load( new StringReader(designer.Text)); // would return a DynamicActivity for your case
ActivityValidationServices.Validate(a);
(全文完)
以下为广告部分
您部署的HTTPS网站安全吗?
如果您想看下您的网站HTTPS部署的是否安全,花1分钟时间来 myssl.com 检测以下吧。让您的HTTPS网站变得更安全!
快速了解HTTPS网站安全情况。
安全评级(A+、A、A-...)、行业合规检测、证书信息查看、证书链信息以及补完、服务器套件信息、证书兼容性检测等。
安装部署SSL证书变得更方便。
SSL证书内容查看、SSL证书格式转换、CSR在线生成、SSL私钥加解密、CAA检测等。
让服务器远离SSL证书漏洞侵扰
TLS ROBOT漏洞检测、心血漏洞检测、FREAK Attack漏洞检测、SSL Poodle漏洞检测、CCS注入漏洞检测。