在工作流开发中,邮件通知是必不可少。这篇文章中,我将是使用WF4.0一步一步打造一个功能完整的邮件通知节点。

首先,新建一个WorkflowConsoleApplication项目,改名为MailNoticeDemo,如下图:

添加一个CodeActivity活动命名为MailNotice,添加一个ActivityDesigner活动命名为MailNoticeDesigner。项目结构如下图:

MailNotice用于写发送邮件的业务逻辑,MailNoticeDesigner用于设计活动的界面,现在MailNotice和MailNoticeDesigner是没有任何关联的,我们在MailNotice类上添加[Designer(typeof(MailNoticeDesigner))],关联MailNotice和MailNoticeDesigner,还需要引入System.ComponentModel命名空间,代码如下。

  1. using System.Activities;
    using System.ComponentModel;
    using System.Activities.Presentation.Metadata;
    using System.Activities.Presentation.PropertyEditing;
    using System;
    namespace MailNoticeDemo
    {
    [Designer(typeof(MailNoticeDesigner))]
    public sealed class MailNotice : CodeActivity
    {
  2.                  ………
  3. }

这时,MailNotice和MailNoticeDesigner活动中还没有进行编码。在项目中引入一个邮件发送类MailHelper.cs,编写MailNotice代码,如下:

  1. [Designer(typeof(MailNoticeDesigner))]

    1.  public sealed class MailNotice : CodeActivity
      
    2. {
      
    3.      public InArgument<string> Receive { get; set; }
      
    4.      public InArgument<string> Subject { get; set; }
      
    5.      public InArgument<string> Content { get; set; }
      
    6.      public string Attachment { get; set; }
      
    7.      static MailNotice()
      
    8.      {
      
    9.          AttributeTableBuilder builder = new AttributeTableBuilder();
      
    10.          builder.AddCustomAttributes(typeof(MailNotice), "Attachment", new EditorAttribute(typeof(FilePickerEditor), typeof(DialogPropertyValueEditor)));
      
    11.          MetadataStore.AddAttributeTable(builder.CreateTable());
      
    12.      }
      
    13.      // If your activity returns a value, derive from CodeActivity<TResult>
      
    14.      // and return the value from the Execute method.
      
    15. protected override void Execute(CodeActivityContext context)
      
    16.      {
      
    17.          SMTP smtp = new SMTP("你邮箱地址·", "显示的名称", new string[] { Receive.Get(context) }, null, null, Subject.Get(context), Content.Get(context), new string[] { Attachment }, "邮件发送服务", 25, "你邮箱地址·", "你邮箱密码", false);
      
    18.          try
      
    19. {
      
    20.              smtp.Send();
      
    21.          }
      
    22.         catch (Exception ex)  
    23.          { 
    24.             string error = ex.Message; 
    25.              if (ex.InnerException != null) 
    26.              { 
    27.                   error = ex.InnerException.Message;
      
    28.              }
    29.               Console.WriteLine("邮箱发送失败: " + error); 
    30.           }}
    31.  }
    32. 设计MailNoticeDesigner活动的UI,设计UI之前让你可以先了解一下ExpressionTextBox。详见:expressiontextbox-101
    33. 通过expressiontextbox和WPF的控件,设计UI界面如下:
    34.  
    35. Xaml代码如下:
      1. <sap:ActivityDesigner x:Class="MailNoticeDemo.MailNoticeDesigner"
        
      2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        
      3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        
      4. xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
        
      5. xmlns:sapc="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation"
        
      6. xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"
        
      7. mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="221" d:DesignWidth="336">
        
      8.     <sap:ActivityDesigner.Resources>
        
      9.         <ResourceDictionary x:Uid="ResourceDictionary_1">
        
      10.             <sapc:ArgumentToExpressionConverter x:Uid="sadv:ArgumentToExpressionConverter_1" x:Key="ArgumentToExpressionConverter" />
        
      11.         </ResourceDictionary>
      12.         </sap:ActivityDesigner.Resources>
        
      13.         <Grid Height="190" Width="328">
        
      14.         <Grid.RowDefinitions>
        
      15.             <RowDefinition Height="28"></RowDefinition>
        
      16.             <RowDefinition  Height="28"></RowDefinition>
        
      17.             <RowDefinition  Height="54"></RowDefinition>
        
      18.             <RowDefinition Height="47" />
        
      19.             <RowDefinition Height="31*" />
        
      20.         </Grid.RowDefinitions>
        
      21.         <Grid.ColumnDefinitions>
        
      22.             <ColumnDefinition Width=".2*"></ColumnDefinition>
        
      23.             <ColumnDefinition Width=".8*"></ColumnDefinition>
        
      24.         </Grid.ColumnDefinitions>
        
      25.         <Label Content="收件人" Height="28" HorizontalAlignment="Left" Grid.Row="0" Grid.Column="0" Name="label1" VerticalAlignment="Top" />
        
      26.         <sapv:ExpressionTextBox  Grid.Row="0" Grid.Column="1"
        
      27. OwnerActivity="{Binding Path=ModelItem}"
        
      28. Expression="{Binding Path=ModelItem.Receive, Mode=TwoWay, Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=In }"
        
      29. UseLocationExpression="False"   />
        
      30.         <Label Content="主题:"  Grid.Row="1" Grid.Column="0"  HorizontalAlignment="Left"  Name="label2" VerticalAlignment="Top" />
        
      31.         <sapv:ExpressionTextBox  Grid.Row="1" Grid.Column="1"
        
      32. OwnerActivity="{Binding Path=ModelItem}"
        
      33. Expression="{Binding Path=ModelItem.Subject, Mode=TwoWay, Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=In }"
        
      34. UseLocationExpression="False"   />
        
      35.         <Label Content="正文:" Grid.Row="2" HorizontalAlignment="Left"  Name="label3" VerticalAlignment="Top"   />
        
      36.         <sapv:ExpressionTextBox  Grid.Row="2" Grid.Column="1"
        
      37. OwnerActivity="{Binding Path=ModelItem}"
        
      38. Expression="{Binding Path=ModelItem.Content, Mode=TwoWay, Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=In }"
        
      39. UseLocationExpression="False" Margin="0,0,0,1" Grid.RowSpan="2" />
        
      40.     </Grid>
        
      41. </sap:ActivityDesigner>
        
  2. 这样我们就完成了这个邮件活动。测试一下。在Workflow1中拖入这个活动。输入收件人、主题、正文,如下图:
  3.  设置附件,如下图:
  4. 启动工作流发送邮件:
    1. WorkflowInvoker.Invoke(new Workflow1()); 
  5. 你会发现这个活动的图标不够美观,让我们修改一下这个自定义活动的图标。 在MailNoticeDesigner.xaml中加入下面代码
  6. <sap:ActivityDesigner.Icon>
    1.         <DrawingBrush>
    2.             <DrawingBrush.Drawing>
    3.                 <ImageDrawing>
    4.                     <ImageDrawing.Rect>
    5.                         <Rect Location="0,0" Size="16,16" ></Rect>
    6.                     </ImageDrawing.Rect>
    7.                     <ImageDrawing.ImageSource>
    8.                         <BitmapImage UriSource="mail.ico" ></BitmapImage>
    9.                     </ImageDrawing.ImageSource>
    10.                 </ImageDrawing>
    11.             </DrawingBrush.Drawing>
    12.         </DrawingBrush>
    13.     </sap:ActivityDesigner.Icon>
    14. 设置图标mail.ico,将Build action设置为Resource,如下图:
    15.  
    16. 看一下我们最终打造的邮件活动:
    17. 总结:这篇文章详细讲解了创建WF4.0一个自定义活动的完整过程,虽然很简单,但对创建自定义活动很有参考价值。

本文转自麒麟博客园博客,原文链接:http://www.cnblogs.com/zhuqil/archive/2010/04/29/WFMAIL.html,如需转载请自行联系原作者

WF4.0实战(十一):邮件通知相关推荐

  1. WF4.0实战系列索引

    从WF4.0 betal1出来的时候就开始使用WF4.0,由于资料不多,学习过程也非常艰苦.今年四月份的时候打算写WF4.0实战系列,由于今年是本命年故坚持写了24篇文章.这个系列的文章都有一个特点, ...

  2. WF4.0实战(十):分布式酒店订房系统

    这篇文章主要是实现一个分布式的酒店订房功能.主要阐述如何通过WCF加WF实现一个分布式系统模型. 这个Demo的场景说明: 一家酒店将房间信息存储在SQL Server数据库中,酒店的工作人员根据客户 ...

  3. WF4.0实战(四):博客申请流程

    概述: 我是两年前申请的博客园.如今仍然记得很清楚,与现在的方式有点不同,当时注册也是要申请的,现在是注册不需要申请,而注册之后,开博需要申请.当时感觉有点新鲜,同样也感到欣慰,有如此敬业的管理员已经 ...

  4. WF4.0实战(六):控制WPF动画

    这个例子改造了王晓冬老师的:用WF流程控制WPF动画. 本文用一个小例子演示了在WF中定义两个操作步骤,用来控制WPF页面元素的动画.王冬老师当时使用的是WF3.0,现在我改成WF4.0. 先看效果: ...

  5. WF4.0实战(七):请假流程(带驳回操作)

    我使用WF4.0有很长一段时间了,但是对WF3.0和WF3.5自知甚少,对状态机也不甚了解.今天生鱼片前辈的博文:WF4实现工作流驳回流转模型的几种设计方案 中提出的四中实现驳回的方式中.第一种大家都 ...

  6. WF4.0实战(九):猜数字游戏,测下你的智力

    今天周末,用WF4.0写个小游戏,供大家娱乐一下.界面做的不是很美观,请见谅. 效果: 一运行程序,游戏就开始了. 你输入一个数字4,提示"尝试输入一个较大的数字",如下图: 你输 ...

  7. WF4.0实战(十五):伤心聊天室

    大家都知道,一般能使用WCF的Callback Contract能实现聊天室.这篇文章我将使用WF4.0是实现我的伤心聊天室.先看效果,再讲如何实现和使用WF4.0的优势,最后总结.界面很简洁,请见谅 ...

  8. WF4.0实战(二):超市收银软件

    今天翻到了伍迷前辈的大话设计模式中的<第二章 商场促销-策略模式>.我感觉用WF去实现,比较简单直观,我很喜欢做简单的事情.故使用了伍迷前辈书中的两个主要人物小菜和大鸟,写下这篇博客. 时 ...

  9. WF4.0实战(一):文件审批流程

    http://www.cnblogs.com/zhuqil/archive/2010/04/13/DocumentApprovalProcess.html 转载于:https://www.cnblog ...

最新文章

  1. Laravel7使用Auth进行用户认证
  2. Java中 实现通过文件夹选择任一图像,从而进行图像卷积操作
  3. 微信支付(JSAPI) - chooseWXPay fail 问题解决
  4. linux数据流重定向
  5. Angular和SAP C4C的事件处理队列 1
  6. ue4缓存位置怎么改_怎么从蓝图节点跳转到C++源码?
  7. oc之Mac-响应链(Responder Chain)
  8. WebSocket之JS发送二进制
  9. java 比较源文件_Beyond Compare比较Java源代码文件的详细操作方法
  10. 【Python】爬虫爬取各大网站新闻(一)
  11. HLS 开发学习(五) 稀疏矩阵向量乘法
  12. 【自动驾驶】高级驾驶辅助系统(ADAS)
  13. 研究生毕业论文如何选题
  14. 解决active样式在ios手机上没有生效的问题
  15. java飘落的雪花_[Java教程]树叶飘落、雪花飘落等同时多个图片飘落
  16. 【Android Dialog】Dialog
  17. 诺奖以上,真相未满:追捕黑洞二百年
  18. python算法教程百度云_如何用免费GPU学习AI算法?这篇算法资源大集锦别错过
  19. 自己写的C盘清理工具 Ver1.0.0
  20. 微信小程序视频点播在线视频学习系统 毕业设计 课程设计(5)视频播放页面

热门文章

  1. 记一次中台数据传输同步Elasticsearch失败的车祸现场
  2. OpenCV调用TensorFlow预训练模型
  3. Springboot搭建个人博客系列
  4. Android 点击应用外的Url拉起应用
  5. SDNU 1167.花生采摘(排序)
  6. (原创)机器学习之numpy库中常用的函数介绍(一)
  7. UI渲染回顾简单笔记
  8. 招行率先落地房贷新政 其他银行细则仍在制定
  9. SQL Server导入导出工具弱爆了
  10. silverlight mediaElement 动态添加source