WF4.0实战(二十三):自定义工作流活动的外观的两种方式

    经常有童鞋在群里面问同样一个问题:如何自定义WF4.0活动的外观。其实一共有两种方式去实现自定义WF4.0活动的外观:一种方式我在以前的博文上实现过,见:WF4.0实战(十一):邮件通知;另外一种方式我将在这里讲述它的实现。故这篇文章中,我将分别用这两种方式去一个最简单的WF4.0自定义活动外观的例子。

    第一种方式:使用[Designer]属性。命名空间为:using System.ComponentModel;代码如下:

[Designer(typeof(CustomWriteLineDesigner))]
public sealed class CustomWriteLine : CodeActivity
{
    [RequiredArgument]
    public InArgument<string> Text { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
        Console.WriteLine(context.GetValue(this.Text));
    }
}

上面代码中的CustomWriteLineDesigner是自定义外观的XAML文件。第一种方式代码还可以这样写:

[("MyActivityDesigner.CustomWriteLineDesigner,MyActivityDesigner")]
 public sealed class CustomWriteLine : CodeActivity
 {
     [RequiredArgument]
     public InArgument<string> Text { get; set; }

     protected override void Execute(CodeActivityContext context)
     {
         Console.WriteLine(context.GetValue(this.Text));
     }
 }

CustomWriteLineDesigner的代码如下:

<sap:ActivityDesigner x:Class="MyActivityDesigner.CustomWriteLineDesigner"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sadc="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation" 
    xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
    xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation">
    <sap:ActivityDesigner.Resources>
        <sadc:ArgumentToExpressionConverter x:Key="argConverter"/>
    </sap:ActivityDesigner.Resources>
    <sap:ActivityDesigner.Icon>
        <DrawingBrush>
            <DrawingBrush.Drawing>
                <ImageDrawing>
                    <ImageDrawing.Rect>
                        <Rect Location="0,0" Size="16,16" ></Rect>
                    </ImageDrawing.Rect>
                    <ImageDrawing.ImageSource>
                        <BitmapImage UriSource="WriteLine.jpg" ></BitmapImage> 
                    </ImageDrawing.ImageSource> 
                </ImageDrawing> 
            </DrawingBrush.Drawing>
        </DrawingBrush>
    </sap:ActivityDesigner.Icon>
    <Grid >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <TextBlock Text="Text " Padding="0,2,4,2"/>
        <sapv:ExpressionTextBox MaxLines="1" Grid.Column="1" Width="200" 
                                    Expression="{Binding Path=ModelItem.Message, Mode=TwoWay, Converter={StaticResource argConverter}, ConverterParameter=In}" 
                                    OwnerActivity="{Binding Path=ModelItem}" />
    </Grid>
</sap:ActivityDesigner>

效果:

jjj

以上是第一种方式,如果有不清楚的地方可以参考:WF4.0实战(十一):邮件通知

第二种方式:代码关联去实现

    上面的方式是硬编码实现的,有些不够灵活,微软内置的活动是采用第二种方式,而不是第一种方式。下面我将一步一步教你如何用第二种方式去实现同样的效果。

    新建一ActivityLibrary项目命名为:MyActivityDesignerTwo,新建一个ActivityDesignerLibrary项目命名为MyActivityDesignerTwo.Design。从命名上可以看出,MyActivityDesignerTwo用于实现后台的逻辑代码。MyActivityDesignerTwo.Design用于实现自定义活动的UI。项目结构如下图所示:

yy

    其中CustomWriteLineDesigner.xaml代码和第一种方式相同。不同的是多出了一个DesignerMetadata.cs,CustomWriteLine.cs中去掉了Designer属性的代码,去掉了Designer属性的CustomWriteLine代码如下:

public sealed class CustomWriteLine : CodeActivity
{
    [RequiredArgument]
    public InArgument<string> Text { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
        Console.WriteLine(context.GetValue(this.Text));
    }
}

DesignerMetadata.cs的代码如下:

public class DesignerMetadata : IRegisterMetadata
{
    /// <summary>
    /// Register the designer for the write line activity
    /// </summary>
    public void Register()
    {
        AttributeTableBuilder builder = new AttributeTableBuilder();

        Type t = typeof(CustomWriteLine);

        builder.AddCustomAttributes(t, new DesignerAttribute(typeof(CustomWriteLineDesigner)));

        MetadataStore.AddAttributeTable(builder.CreateTable());
    }
}

    后台的代码和UI的设计并不在同一个项目中,我们如何将他们关联起来呢?很简单,我们只要将两个项目生成的dll放在同一个目录下面就OK了。我们修改MyActivityDesignerTwo.Design的生成路径。如下图:

gg

    新建一个测试的WorkflowConsoleApplication项目,在这个项目中添加MyActivityDesignerTwo引用。

    我们将微软内置的WriteLine和刚才定义的活动做个比较,如下图:

gg22

   你会发现有一个明显不同的地方:我们自定义的活动比微软内置的活动要宽一些。Text属性上我们自定义的WriteLine活动上显示全部的文字:"这个我们自定义的WriteLine活动",而内置的活动隐藏了部分文字没有显示。这一点的是蛮有好处的:在流程设计器上自定义的活动比内置的活动更加直观。

总结:这篇文章教你用两种方式去实现自定义活动的外观。有人可能会问为什么要自定义活动的外观,一个CustomWriteLine就好了呀!自定义活动的外观的好处是使流程设计器上更加直观。只有很直观了,我们的流程设计器才能拿给普通用户使用。

代码:http://files.cnblogs.com/zhuqil/MyActivityDesigner.rar


原文链接: http://www.cnblogs.com/zhuqil/archive/2010/06/27/two-way-implement-wf4-custom-activity.html

你可能感兴趣的:(WF4.0实战(二十三):自定义工作流活动的外观的两种方式)