上一篇: 宿主工作流设计器(三)
快过年了,估计这是过年前最后一篇POST了,总算也可以基本说完宿主工作流的工作了,在专攻代码前我们先回顾一下前面的内容,前面我们已经知道如何改变工作流设计器中的标题,我们可以用继承自SequentialWorkflowRootDesigner的类来构造工作流的设计类,同样的本篇我们看看活动外观的定制,对于活动我们可以继承自ActivityDesigner类构造:
重写Text属性可以让我们在活动上显示自定义的文字:
我们先定义一个特性作用于活动类之上,可以这样写:
在Desinger类中重写Initialize方法获取这个特性的Text属性:
这样只要每个活动应用CustomerAttribute特性就可以让他显示我们定制的外观,例如我们上面的Initialize方法是在类CustomerDesigner中,活动就可以这样定义:
活动背景颜色:
每一个ActivityDesigner都可以应用一个ActivityDesignerTheme特性来控制它的主题外观,例如我们继承一个ActivityDesignerTheme来构造主题:
这样我们实现了活动背景为横向渐变颜色,起始颜色是WhiteSmoke,结束颜色是LightSkyBlue,活动边框颜色是LightSteelBlue,当然还有更多的行为可以在ActivityDesignerTheme中定制。这个类构造好后作用于上面的CustomerDesigner上:
更多的定制:
重写CustomerDesigner的OnPaint方法可以在设计器上绘制我们希望的图形,下面是一个我花了三小时来绘制活动的描述文字到它的图形上(GDI+真不是人弄的,自己汗一个!),下面的图也应用了我们上面的所有代码:
活动行为:
我们可以在CustomerDesigner过滤一些事件消息,继承一个WorkflowDesignerMessageFilter类来实现自己的消息过滤器:
重写CustomerDesigner的MessageFilters方法:
重写Verbs属性获得右键自定义操作自定义操作:
同样的重写SmartTagVerbs属性同时设置ShowSmartTag为true可以在活动节点上出现SmartTag上下文菜单,一个典型的例子就是VS工作流设计器中的工作流节点上的View SequentialWorkflow, View Cancel Handler和View Fault Handlers菜单。
好了,到这里这个系列算完结了,我有一点点疑惑,活动Desinger类中的ShowInfoTip无论怎么样也不工作,而工作流中的TooTip无论怎样也屏蔽不了,不知谁解决了这个问题麻烦告知一声。
快过年了,估计这是过年前最后一篇POST了,总算也可以基本说完宿主工作流的工作了,在专攻代码前我们先回顾一下前面的内容,前面我们已经知道如何改变工作流设计器中的标题,我们可以用继承自SequentialWorkflowRootDesigner的类来构造工作流的设计类,同样的本篇我们看看活动外观的定制,对于活动我们可以继承自ActivityDesigner类构造:
重写Text属性可以让我们在活动上显示自定义的文字:
public override string Text
{
get
{
return "我的活动";
}
}
但是这样做缺乏灵活性,我们必须每一个活动都为他写一个Designer类,因此换种方法实现,重写Initialize方法:{
get
{
return "我的活动";
}
}
我们先定义一个特性作用于活动类之上,可以这样写:
[AttributeUsage(AttributeTargets.Class)]
public class CustomerAttribute : Attribute
{
public CustomerAttribute(string text)
{
this.Text = text;
}
public string Text { get; private set; }
}
public class CustomerAttribute : Attribute
{
public CustomerAttribute(string text)
{
this.Text = text;
}
public string Text { get; private set; }
}
在Desinger类中重写Initialize方法获取这个特性的Text属性:
protected override void Initialize(System.Workflow.ComponentModel.Activity activity)
{
base.Initialize(activity);
this.Description = activity.Description;
Type ty = activity.GetType();
AttributeCollection attrs = TypeDescriptor.GetAttributes(ty);
CustomerAttribute dAttr = attrs[typeof(CustomerAttribute)] as CustomerAttribute;
if (dAttr != null)
{
this.Text = dAttr.Text;
}
}
{
base.Initialize(activity);
this.Description = activity.Description;
Type ty = activity.GetType();
AttributeCollection attrs = TypeDescriptor.GetAttributes(ty);
CustomerAttribute dAttr = attrs[typeof(CustomerAttribute)] as CustomerAttribute;
if (dAttr != null)
{
this.Text = dAttr.Text;
}
}
这样只要每个活动应用CustomerAttribute特性就可以让他显示我们定制的外观,例如我们上面的Initialize方法是在类CustomerDesigner中,活动就可以这样定义:
[Customer("我的活动")]
[Designer(typeof(CustomerDesigner), typeof(IDesigner))]
[Serializable]
public partial class MyActivityOne : SequenceActivity
{
}
[Designer(typeof(CustomerDesigner), typeof(IDesigner))]
[Serializable]
public partial class MyActivityOne : SequenceActivity
{
}
活动背景颜色:
每一个ActivityDesigner都可以应用一个ActivityDesignerTheme特性来控制它的主题外观,例如我们继承一个ActivityDesignerTheme来构造主题:
public class CustomActivityDesignerTheme : ActivityDesignerTheme
{
public CustomActivityDesignerTheme(WorkflowTheme theme) : base(theme)
{
this.BackColorStart = Color.WhiteSmoke;
this.BackColorEnd = Color.LightSkyBlue;
this.BackgroundStyle = System.Drawing.Drawing2D.LinearGradientMode.Horizontal;
this.BorderColor = Color.LightSteelBlue;
}
}
{
public CustomActivityDesignerTheme(WorkflowTheme theme) : base(theme)
{
this.BackColorStart = Color.WhiteSmoke;
this.BackColorEnd = Color.LightSkyBlue;
this.BackgroundStyle = System.Drawing.Drawing2D.LinearGradientMode.Horizontal;
this.BorderColor = Color.LightSteelBlue;
}
}
这样我们实现了活动背景为横向渐变颜色,起始颜色是WhiteSmoke,结束颜色是LightSkyBlue,活动边框颜色是LightSteelBlue,当然还有更多的行为可以在ActivityDesignerTheme中定制。这个类构造好后作用于上面的CustomerDesigner上:
[ActivityDesignerTheme(typeof(CustomActivityDesignerTheme))]
public class CustomerDesigner : ActivityDesigner
public class CustomerDesigner : ActivityDesigner
更多的定制:
重写CustomerDesigner的OnPaint方法可以在设计器上绘制我们希望的图形,下面是一个我花了三小时来绘制活动的描述文字到它的图形上(GDI+真不是人弄的,自己汗一个!),下面的图也应用了我们上面的所有代码:
活动行为:
我们可以在CustomerDesigner过滤一些事件消息,继承一个WorkflowDesignerMessageFilter类来实现自己的消息过滤器:
class CustomActivityDesignerMessageFilter : WorkflowDesignerMessageFilter
重写CustomerDesigner的MessageFilters方法:
protected override System.Collections.ObjectModel.ReadOnlyCollection<WorkflowDesignerMessageFilter> MessageFilters
{
get
{
if (this.m_messageFilters == null)
{
this.m_messageFilters = new List<WorkflowDesignerMessageFilter>();
foreach (var filter in base.MessageFilters)
{
this.m_messageFilters.Add(filter);
}
this.m_messageFilters.Add(new CustomActivityDesignerMessageFilter());
}
return this.m_messageFilters.AsReadOnly();
}
}
{
get
{
if (this.m_messageFilters == null)
{
this.m_messageFilters = new List<WorkflowDesignerMessageFilter>();
foreach (var filter in base.MessageFilters)
{
this.m_messageFilters.Add(filter);
}
this.m_messageFilters.Add(new CustomActivityDesignerMessageFilter());
}
return this.m_messageFilters.AsReadOnly();
}
}
重写Verbs属性获得右键自定义操作自定义操作:
protected override ActivityDesignerVerbCollection Verbs
{
get
{
ActivityDesignerVerb showMsgVerb = new ActivityDesignerVerb(this, DesignerVerbGroup.View, "ShowMessage", new EventHandler(Click));
base.Verbs.Add(showMsgVerb);
return base.Verbs;
}
}
private void Click(object sender, EventArgs e)
{
MessageBox.Show("Text");
}
{
get
{
ActivityDesignerVerb showMsgVerb = new ActivityDesignerVerb(this, DesignerVerbGroup.View, "ShowMessage", new EventHandler(Click));
base.Verbs.Add(showMsgVerb);
return base.Verbs;
}
}
private void Click(object sender, EventArgs e)
{
MessageBox.Show("Text");
}
同样的重写SmartTagVerbs属性同时设置ShowSmartTag为true可以在活动节点上出现SmartTag上下文菜单,一个典型的例子就是VS工作流设计器中的工作流节点上的View SequentialWorkflow, View Cancel Handler和View Fault Handlers菜单。
好了,到这里这个系列算完结了,我有一点点疑惑,活动Desinger类中的ShowInfoTip无论怎么样也不工作,而工作流中的TooTip无论怎样也屏蔽不了,不知谁解决了这个问题麻烦告知一声。