Workflow表单的作用是能够在客户端进行表单设计,然后在流程中动态开放哪些输入框可以供用户填写。

在这里我扩展了一个常用的WebEditor工具——KindEditor,能够插入自定义的html符号,如下图:

Form类如下:

  1. public delegate string SetAutoCompleteValue(string autoCompleteType);
  2.  
  3. [Serializable]
  4. public class Form
  5. {
  6. [XmlAttribute]
  7. public Guid FormId { get; set; }
  8. [XmlAttribute]
  9. public string FormName { get; set; }
  10. [XmlAttribute]
  11. public string FormCategory { get; set; }
  12. [XmlAttribute]
  13. public string FormContent { get; set; }
  14. [XmlAttribute]
  15. public DateTime CreateDate { get; set; }
  16. public Person Creator { get; set; }
  17.  
  18. public string CreaterName
  19. {
  20. get { return Creator != null ? Creator.PersonName : ""; }
  21. }
  22.  
  23. public List<FormControl> FormControls { get; set; }
  24.  
  25. public void InitializeFormControls()
  26. {
  27. if (!string.IsNullOrEmpty(FormContent))
  28. {
  29. const string pattern = @"\<input(.*?)\/>";
  30. var rx = new Regex(pattern);
  31. var matches = rx.Matches(FormContent);
  32. var formControls = new List<FormControl>();
  33. foreach (Match match in matches)
  34. {
  35. string fieldLabel = Convert.ToString(match.Groups[]); //Group[0] :[xx],Group[1]: xx
  36. string[] para = fieldLabel.Split(' ');
  37.  
  38. var values = para.First(s => s.Trim().ToLower()
  39. .StartsWith("value=")).Replace("value=", "").Replace("\"", "");
  40.  
  41. string[] sArray = Regex.Split(values, "//", RegexOptions.IgnoreCase);
  42.  
  43. bool isNewControl = true;
  44. string controlId = string.Empty;
  45. if (para.Any(p => p.StartsWith("id=")))
  46. {
  47. isNewControl = false;
  48. controlId = para.First(s => s.Trim().ToLower()
  49. .StartsWith("id=")).Replace("id=", "").Replace("\"", "");
  50. }
  51.  
  52. if (sArray.Count() >= ) //每个输入框表单至少要有三个以上属性
  53. {
  54. FormControl formControl ;
  55. if (isNewControl)
  56. {
  57. switch (sArray[])
  58. {
  59. case "单行":
  60. formControl = new TextLineFormControl();
  61. formControl.Width = int.Parse(sArray[]);
  62. break;
  63. case "多行":
  64. formControl = new MultiLineFormControl();
  65. formControl.Width = int.Parse(sArray[]);
  66. formControl.Height = int.Parse(sArray[]);
  67. break;
  68. case "单选":
  69. formControl = new RadioFormControl();
  70. formControl.InitialData = sArray[];
  71. break;
  72. case "多选":
  73. formControl = new CheckBoxFormControl();
  74. formControl.InitialData = sArray[];
  75. break;
  76. case "下拉":
  77. formControl = new DropDownFormControl();
  78. formControl.InitialData = sArray[];
  79. break;
  80. case "自动":
  81. formControl = new AutoCompleteFormControl();
  82. formControl.InitialData = sArray[];
  83. break;
  84. default:
  85. formControl = new UnknowFormControl();
  86. break;
  87. }
  88. formControl.FieldName = sArray[];
  89. formControl.ControlId = Guid.NewGuid();
  90.  
  91. }
  92. else
  93. {
  94. formControl = FormControls.Single(f => f.ControlId == Guid.Parse(controlId));
  95. switch (sArray[])
  96. {
  97. case "单行":
  98. formControl.Width = int.Parse(sArray[]);
  99. break;
  100. case "多行":
  101. formControl.Width = int.Parse(sArray[]);
  102. formControl.Height = int.Parse(sArray[]);
  103. break;
  104. case "单选":
  105. formControl.InitialData = sArray[];
  106. break;
  107. case "多选":
  108. formControl.InitialData = sArray[];
  109. break;
  110. case "下拉":
  111. formControl.InitialData = sArray[];
  112. break;
  113. case "自动":
  114. formControl.InitialData = sArray[];
  115. break;
  116. default:
  117. break;
  118. }
  119. }
  120.  
  121. formControls.Add(formControl);
  122. FormContent = FormContent.Replace(match.Value,
  123. string.Format("{{{0}}}", formControl.ControlId));
  124. }
  125.  
  126. }
  127. FormControls = formControls;
  128. FormContent = FormContent;
  129. }
  130. }
  131.  
  132. public string GetOccupyContentString()
  133. {
  134. var str = FormContent;
  135. foreach (var formControl in FormControls)
  136. {
  137. str = str.Replace(string.Format("{{{0}}}", formControl.ControlId), formControl.GetDesignString());
  138. }
  139. return str;
  140. }
  141.  
  142. public string GetPreviewContentString()
  143. {
  144. var str = FormContent;
  145.  
  146. foreach (var formControl in FormControls)
  147. {
  148. str = str.Replace(string.Format("{{{0}}}", formControl.ControlId), formControl.GetInputString());
  149. }
  150. return str;
  151. }
  152.  
  153. public string GetPreviewContentString(Dictionary<Guid, string> writedValues)
  154. {
  155. var str = FormContent;
  156.  
  157. foreach (var formControl in FormControls)
  158. {
  159. string value = null;
  160. if (writedValues != null && writedValues.TryGetValue(formControl.ControlId, out value))
  161. {
  162. str = str.Replace(string.Format("{{{0}}}", formControl.ControlId), value);
  163. }
  164. else
  165. {
  166. str = str.Replace(string.Format("{{{0}}}", formControl.ControlId), string.Empty);
  167. }
  168. }
  169. return str;
  170. }
  171.  
  172. public string GetDisplayContent(List<Guid> canWriteformControlIds, SetAutoCompleteValue autoCompleteValue, Dictionary<Guid, string> writedValues = null)
  173. {
  174. var str = FormContent;
  175.  
  176. foreach (var formControl in FormControls)
  177. {
  178. if (canWriteformControlIds.Contains(formControl.ControlId))
  179. {
  180. string value = null;
  181. if (writedValues != null && writedValues.TryGetValue(formControl.ControlId, out value))
  182. {
  183. formControl.FieldValue = value;
  184. }
  185. if (string.IsNullOrEmpty(value) && formControl is AutoCompleteFormControl &&
  186. !string.IsNullOrEmpty(formControl.InitialData) && autoCompleteValue != null)
  187. {
  188. formControl.FieldValue = autoCompleteValue(formControl.InitialData);
  189. }
  190. str = str.Replace(string.Format("{{{0}}}", formControl.ControlId), formControl.GetInputString());
  191. }
  192. else
  193. {
  194. string value = string.Empty;
  195. if (writedValues != null && writedValues.TryGetValue(formControl.ControlId, out value))
  196. {
  197. formControl.FieldValue = value;
  198. }
  199. str = str.Replace(string.Format("{{{0}}}", formControl.ControlId), value);
  200. }
  201. }
  202. return str;
  203. }
  204. }

[Serializable]标识是为了能序列化类;

[XmlAttribute]是为了在持久化保存到数据库的时候使用XML特性,节约保存控件,便于查询操作。

InitializeFormControls:从编辑器中读入的代码进行初始化;

其它的方法基本用于前台呈现。

FormControl类如下:

基类:

  1. [Serializable]
  2. [XmlInclude(typeof(TextLineFormControl))]
  3. [XmlInclude(typeof(MultiLineFormControl))]
  4. [XmlInclude(typeof(RadioFormControl))]
  5. [XmlInclude(typeof(CheckBoxFormControl))]
  6. [XmlInclude(typeof(DropDownFormControl))]
  7. [XmlInclude(typeof(AutoCompleteFormControl))]
  8. [XmlInclude(typeof(UnknowFormControl))]
  9. public abstract class FormControl
  10. {
  11. [XmlAttribute]
  12. public Guid ControlId { get; set; }
  13. [XmlAttribute]
  14. public string FieldName { get; set; }
  15. [XmlAttribute]
  16. public string FieldValue { get; set; }
  17. [XmlAttribute]
  18. public int Width { get; set; }
  19. [XmlAttribute]
  20. public int Height { get; set; }
  21. [XmlAttribute]
  22. public string ToolTip { get; set; }
  23. [XmlAttribute]
  24. public bool Required { get; set; }
  25. [XmlAttribute]
  26. public bool CanWrite { get; set; }
  27. [XmlAttribute]
  28. public string InitialData { get; set; }
  29. public abstract string GetDesignString();
  30. public abstract string GetInputString();
  31. }

[XmlInclude(typeof(TextLineFormControl))]..... 为了持久化时能够将派生类兼容存储;

GetDesignString:在设计器里呈现的方式;

GetInputString:在让用户输入时呈现的代码。

几个派生类:

  1. [Serializable]
  2. public class TextLineFormControl : FormControl
  3. {
  4. public override string GetDesignString()
  5. {
  6. return string.Format("<input type=\"text\" value=\"{0}//{1}//{2}\" style=\"{3}\" id=\"{4}\">",
  7. WorkflowConstant.TextBoxFormControlName, FieldName, Width, WorkflowConstant.ControlDesignWidth,ControlId);
  8. }
  9.  
  10. public override string GetInputString()
  11. {
  12. return string.Format("<input type=\"text\" value=\"{0}\" id=\"{1}\" size=\"{2}\" maxlength=\"{2}\" name=\"{1}\" >",
  13. FieldValue, ControlId, Width);
  14. }
  15. }
  16.  
  17. [Serializable]
  18. public class MultiLineFormControl : FormControl
  19. {
  20. public override string GetDesignString()
  21. {
  22. return string.Format("<input type=\"text\" value=\"{0}//{1}//{2}//{5}\" style=\"{3}\" id=\"{4}\">",
  23. WorkflowConstant.TextAreaFormControlName, FieldName, Width, WorkflowConstant.ControlDesignWidth, ControlId, Height);
  24. }
  25.  
  26. public override string GetInputString()
  27. {
  28. return string.Format("<textarea cols=\"{2}\" rows=\"{3}\" id=\"{1}\" name=\"{1}\" >{0}</textarea>",
  29. FieldValue != null ? FieldValue.Replace("<br/>", "\n\r") : string.Empty, ControlId, Width, Height);
  30. }
  31. }
  32.  
  33. [Serializable]
  34. public class RadioFormControl : FormControl
  35. {
  36. public override string GetDesignString()
  37. {
  38. return string.Format("<input type=\"text\" value=\"{0}//{1}//{2}\" style=\"{3}\" id=\"{4}\">",
  39. WorkflowConstant.RadioFormControlName, FieldName, InitialData, WorkflowConstant.ControlDesignWidth, ControlId);
  40. }
  41.  
  42. public override string GetInputString()
  43. {
  44. StringBuilder sb= new StringBuilder();
  45. var data = InitialData.Split('|');
  46. for (int i = ; i < data.Length; i ++)
  47. {
  48. sb.AppendFormat("<input type=\"radio\" name=\"{0}\" id=\"{0}-{1}\" value=\"{2}\" {3}/>", ControlId, i,
  49. data[i], FieldValue == data[i] ? " checked=\"checked\"" : string.Empty);
  50. sb.AppendFormat("<label for=\"{0}-{1}\">{2}</label>", ControlId, i, data[i]);
  51. }
  52. return sb.ToString();
  53. }
  54. }
  55. .........

Form类使用InitializeFormControls方法生成各种实例化控件,放在FormControls字段里。

这两个类使用的基本上是领域模型。

本系列导航:

  1. .net之工作流工程展示及代码分享(预告)
  2. .net之工作流工程展示及代码分享(一)工作流表单
  3. .net之工作流工程展示及代码分享(二)工作流引擎
  4. .net之工作流工程展示及代码分享(三)数据存储引擎
  5. .net之工作流工程展示及代码分享(四)主控制类
  6. .net之工作流工程展示及代码分享(五)前端交互

.net之工作流工程展示及代码分享(一)工作流表单的更多相关文章

  1. .net之工作流工程展示及代码分享(四)主控制类

    现在应该讲主控制类了,为了不把系统弄得太复杂,所以就用一个类作为主要控制类(服务类),作为前端.后端.业务逻辑的控制类. WorkflowService类的类图如下: 该类的构造函数: public ...

  2. .net之工作流工程展示及代码分享(三)数据存储引擎

    数据存储引擎是本项目里比较有特色的模块. 特色一,使用接口来对应不同的数据库.数据库可以是Oracle.Sqlserver.MogoDB.甚至是XML文件.采用接口进行对应: public inter ...

  3. .net之工作流工程展示及代码分享(二)工作流引擎

    在介绍完表单类的时候,接下来介绍工作流引擎,主要由四个类组成,分别是流程.流程步骤.流程实例.流程步骤实例类. 流程类: [Serializable] public class Flow { [Xml ...

  4. .net之工作流工程展示及代码分享(预告)

    最近在帮公司做一个工作流程序模块,要求是可以嵌入到各种现有的程序中去.我想把自己制作的思路和过程同大家分享. 先上一张结构图: 由于该项目我一个人做,所以系统结构不能太复杂. 用到的技术主要有:DDD ...

  5. net之工作流工程展示及代码分享(记录)

    http://www.cnblogs.com/thanks/p/4183235.html

  6. KindEditor设置为过滤模式,但在代码模式下提交表单时不过虑HTML标签的解决方法

    KindEditor设置filterMode为true,但在代码模式下提交表单的话,发现并没有过虑掉自己不想保留的HTML标签. 这时只需同步内容前加上红色部分内容即可: onClick=" ...

  7. 一段神奇的代码,解决form表单背景偏黄问题

    一段神奇的代码,解决form表框背景偏黄问题 最近在做项目时,发现自己做的挺好看的表单,背景变成了黄色,所以这次折腾了好久终于找到了符合我的决绝办法,现在来分享给大家 一般解决这种input表框偏黄问 ...

  8. 【代码笔记】Web-JavaScript-JavaScript表单验证

    一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  9. 代码段:js表单提交检测

    市面上当然有很多成型的框架,比如jquery的validation插件各种吧.现在工作地,由于前端童鞋也没用这些个插件.根据业务的要求,自己就在代码里写了个简单的表单提交的检测代码(php的也写了一个 ...

随机推荐

  1. JsonTest

    以前用MVC写网站时并不用考虑Json的转换,MVC已经提供了现成的方法. 现在没有用MVC,我就在考虑如何自己转换Json,想来想去自己写还是不够完美,于是尝试了一些其他人写的方法,尝试过微软提供的 ...

  2. apachetop 实时监控apache指定日志

    编译安装,压缩包戳我下载 帮助文档 # apachetop -h ApacheTop v0.12.6 - Usage: File options: -f logfile open logfile (a ...

  3. java 字符流与字节流互转

    package test; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOE ...

  4. 从程序员到CTO的Java技术路线图(我爱分享)

    在技术方面无论我们怎么学习,总感觉需要提升自已不知道自己处于什么水平了.但如果有清晰的指示图供参考还是非常不错的,这样我们清楚的知道我们大概处于那个阶段和水平. Java程序员 高级特性 反射.泛型. ...

  5. composer 自动加载原理

    核心当然是php5加入来的_autoload函数,当实例化一个不存在的类时,在报错之前,如果定义了_autoload函数,会进行调用此函数,此函数就可以执行相关的include操作. <?php ...

  6. 【转载】查看freebsd 服务器硬件信息

    http://3918479.blog.51cto.com/3908479/857900 查看服务器的cpu配置 Fb-bj138# dmesg | grep CPU CPU: Intel(R) Co ...

  7. 解决Entity Framework中DateTime类型字段异常

    从 datetime2 数据类型到 datetime 数据类型的转换产生一个超出范围的值 具体的错误原因是:C#中的DateTime类型比SqlServer中的datetime范围大.SqlServe ...

  8. js正则匹配的一个日常应用

    应用实例 1 /** 将段落中的 \n 转换为 <p></p>, 规范存储 */ 2 function formatParagraphForStore(val) { 3 var ...

  9. 关于复选框input[type=checkbox]

    关于复选框input[type=checkbox],其实在前面的文章中说过一次,当时主要关注点在设置复选框的状态,利用prop实现,今天继续关注一下复选框. 自己在项目中,遇到一个全选/全不选的需求, ...

  10. Intellij 常用技巧-持续更新

    1.快速输入 System.out.println(); sout [TAB] 2.删除Module ctrl+alt+shift+s 调出  Project Structure ,也可点击菜单Fil ...