1.为自定义的Activity添加图标
2.为Activity设置外观
3.为Activity添加右键菜单与数据绑定窗体
4.为Activity添加属性验证器
5.运行时动态将字符串编译为C#可执行代码
最近不少朋友对我以前发的一些例子中的流程设计器有一些疑问,以后我会专门写一个流程设计器的例子,这里先写几个开发流程设计器时要用到的小知识点
1.为自定义的Activity添加图标

为自定义Activity设置成员属性
[System.Drawing.ToolboxBitmap(typeof(wxdActivity), "wxd.bmp")]
public class wxdActivity : System.Workflow.ComponentModel.Activity
2.为Activity设置外观
//设计器样式类
[ActivityDesignerThemeAttribute(typeof(wxdTheme))]
public class wxdActivityDesigner : ActivityDesigner

{
}

//主题类
public class wxdTheme : ActivityDesignerTheme

{
public wxdTheme(WorkflowTheme theme)
: base(theme)

{
this.BorderColor = Color.Red; //边框色
this.BorderStyle = DashStyle.Dash ; //边框线条
this.BackColorStart = Color.White; //渐变开始色
this.BackColorEnd = Color.Blue; //渐变结束色
this.BackgroundStyle = LinearGradientMode.ForwardDiagonal;//渐变方向
}
}
为自定义Activity设置成员属性
[Designer(typeof(wxdActivityDesigner), typeof(IDesigner))]
public class wxdActivity : System.Workflow.ComponentModel.Activity
如果在继承了SequenceActivity的Activity使用了上面方式定义的主题,可以使用其内部Activity结构不显示,有时不想在流程设计器中对用户暴露太多信息可以用这个方法

3.为Activity添加右键菜单与数据绑定窗体
有时使用属性栏对Activity进行设置,对用户来说不是很方便,比如有些属性值是用户名,设备名等要从数据库中动态加载的数据,这时为最好提供一个数据绑定窗体向导
using System.Workflow.ComponentModel;
using System.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel.Design;
using System;
using System.Collections.Generic;
namespace wxwinter


{
//自定义Activity
[Designer(typeof(wxdActivityDesigner), typeof(IDesigner))]
public class wxdActivity : System.Workflow.ComponentModel.Activity

{
public static DependencyProperty wxdValueProperty =

DependencyProperty.Register("wxdValue", typeof(string), typeof(wxdActivity));

[Browsable(true)]
[DesignerSerializationVisibility

(DesignerSerializationVisibility.Visible)]
public string wxdValue

{
get

{
return ((string)(base.GetValue(wxdActivity.wxdValueProperty)));
}
set

{
base.SetValue(wxdActivity.wxdValueProperty, value);
}
}

}


//自定义设计器
public class wxdActivityDesigner : 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, "设置wxdValue", new EventHandler(menu_click));
NewVerbs.Add(menu);

return NewVerbs;
}
}

//当添加的菜单单击时要执行的操作
private void menu_click(object sender, EventArgs e)

{
using (wxdSetForm wf = new wxdSetForm())

{
string v = (string)this.Activity.GetValue

(wxdActivity.wxdValueProperty);

wf.Value = v;
wf.ShowDialog();
this.Activity.SetValue(wxdActivity.wxdValueProperty,wf.Value);
}
}
}

//自定义数据设置窗体
public class wxdSetForm : System.Windows.Forms.Form

{
public string Value;
System.Windows.Forms.TextBox tx = new System.Windows.Forms.TextBox();
System.Windows.Forms.Button bt = new System.Windows.Forms.Button();
public wxdSetForm()

{
bt.Top=30;
this.Controls.Add(tx);
this.Controls.Add(bt);
bt.Click += new EventHandler(bt_Click);
bt.Text = "确定";
this.Load += new EventHandler(wxdSetForm_Load);
}

void wxdSetForm_Load(object sender, EventArgs e)

{
this.tx.Text = Value;
}

void bt_Click(object sender, EventArgs e)

{
this.Value = this.tx.Text;
this.Hide();
}
}
}
以上生成的Activity可以在VS中使用,也可以在我以前的流程设计器例子中使用


4.为Activity添加属性验证器
using System.Workflow.ComponentModel;
using System.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel.Design;
using System;
using System.Collections.Generic;
using System.Workflow.ComponentModel.Compiler;
namespace wxwinter


{
//自定义Activity
[ActivityValidator(typeof(wxdActivityValidator))]
public class wxdActivity : System.Workflow.ComponentModel.Activity

{
public static DependencyProperty wxdValueProperty =

DependencyProperty.Register("wxdValue", typeof(string), typeof(wxdActivity));

[Browsable(true)]
[DesignerSerializationVisibility

(DesignerSerializationVisibility.Visible)]
public string wxdValue

{
get

{
return ((string)(base.GetValue(wxdActivity.wxdValueProperty)));
}
set

{
base.SetValue(wxdActivity.wxdValueProperty, value);
}
}

}
//验证器类
public class wxdActivityValidator :

System.Workflow.ComponentModel.Compiler.ActivityValidator

{
public override ValidationErrorCollection ValidateProperties

(ValidationManager manager, object obj)

{
ValidationErrorCollection Errors = base.ValidateProperties(manager,

obj);

if (obj != null)

{
this.wxdValueValidator(Errors, (wxdActivity)obj);
}
return Errors;
}

private void wxdValueValidator(ValidationErrorCollection Errors,

wxdActivity obj)

{
if (obj.wxdValue=="")

{
Errors.Add(ValidationError.GetNotSetValidationError

(wxdActivity.wxdValueProperty.Name));
}
}

}

}

5.运行时动态将字符串编译为C#可执行代码
(与WF无关,这是C#的基础知识,在作流程设计器时有时会用到)
private void button1_Click(object sender, EventArgs e)

{
CSharpCodeProvider CSharp = new CSharpCodeProvider();


String[] dll =
{ "System.dll", "System.Windows.Forms.dll" };

CompilerParameters 编译参数 = new CompilerParameters(dll);

编译参数.GenerateExecutable = false;

编译参数.GenerateInMemory = true;

string 代码串 = this.textBox1.Text;

CompilerResults 结果 = CSharp.CompileAssemblyFromSource(编译参数, 代

码串);

Assembly 程序集 = 结果.CompiledAssembly;

object 动态对象 = 程序集.CreateInstance("wxd");

MethodInfo 方法 = 动态对象.GetType().GetMethod("setText");


object[] 参数 =
{ this.button1 };

object s = 方法.Invoke(动态对象, 参数);

System.Console.WriteLine(s);

}
文本框中的文本代码
class wxd
{
public string setText(System.Windows.Forms.Control ct)
{
ct.Text = "按钮提示文字被我修改了";
System.Windows.Forms.MessageBox.Show("wxwinter");
return "ok";
}
}

例子:https://files.cnblogs.com/foundation/WindowsApplication1.rar
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)