WF4.0论坛Q/A
偶发现微软的WF4.0论坛也是一个学习WF4.0的好地方,打算把一些典型的问题和答案整理出来,方便大家查阅和学习,先整理几个出来,以后我会持续更新的,WF4.0论坛的地址是:http://social.msdn.microsoft.com/Forums/zh-CN/wfprerelease/threads。
1、Q:获取自定义活动的子活动:
A:实现的代码

{
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:实现的代码:

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等:

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:可以,一个变量情况:

{
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")
}
}
};
}
}
多个变量的情况:

{
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:实现的代码

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:实现的代码:

[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:实现的代码

static SimpleCodeActivity()
{
AttributeTableBuilder builder = new AttributeTableBuilder();
builder.AddCustomAttributes(typeof(SimpleCodeActivity), "FileName", new EditorAttribute(typeof(FilePickerEditor), typeof(DialogPropertyValueEditor)));
MetadataStore.AddAttributeTable(builder.CreateTable());
}
FilePickerEditor:

{
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(ofd.FileName.LastIndexOf('\\')+1);
}
}
}
DataTemplate:

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部分:

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部分:

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。下面是一个代码片段:

{
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的对象和集合初始化语法

New List(Of String) From { "hello", "world" }
New Dictionary(Of String, Object) From { {"hello", 42 }, {"world", new ApplicationException() } }
17、Q:获取Flow switch表达式字符串
A:实现代码:

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",直接看代码:

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注入漏洞检测。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述