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