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

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

Form类如下:

     public delegate string SetAutoCompleteValue(string autoCompleteType);

     [Serializable]
public class Form
{
[XmlAttribute]
public Guid FormId { get; set; }
[XmlAttribute]
public string FormName { get; set; }
[XmlAttribute]
public string FormCategory { get; set; }
[XmlAttribute]
public string FormContent { get; set; }
[XmlAttribute]
public DateTime CreateDate { get; set; }
public Person Creator { get; set; } public string CreaterName
{
get { return Creator != null ? Creator.PersonName : ""; }
} public List<FormControl> FormControls { get; set; } public void InitializeFormControls()
{
if (!string.IsNullOrEmpty(FormContent))
{
const string pattern = @"\<input(.*?)\/>";
var rx = new Regex(pattern);
var matches = rx.Matches(FormContent);
var formControls = new List<FormControl>();
foreach (Match match in matches)
{
string fieldLabel = Convert.ToString(match.Groups[]); //Group[0] :[xx],Group[1]: xx
string[] para = fieldLabel.Split(' '); var values = para.First(s => s.Trim().ToLower()
.StartsWith("value=")).Replace("value=", "").Replace("\"", ""); string[] sArray = Regex.Split(values, "//", RegexOptions.IgnoreCase); bool isNewControl = true;
string controlId = string.Empty;
if (para.Any(p => p.StartsWith("id=")))
{
isNewControl = false;
controlId = para.First(s => s.Trim().ToLower()
.StartsWith("id=")).Replace("id=", "").Replace("\"", "");
} if (sArray.Count() >= ) //每个输入框表单至少要有三个以上属性
{
FormControl formControl ;
if (isNewControl)
{
switch (sArray[])
{
case "单行":
formControl = new TextLineFormControl();
formControl.Width = int.Parse(sArray[]);
break;
case "多行":
formControl = new MultiLineFormControl();
formControl.Width = int.Parse(sArray[]);
formControl.Height = int.Parse(sArray[]);
break;
case "单选":
formControl = new RadioFormControl();
formControl.InitialData = sArray[];
break;
case "多选":
formControl = new CheckBoxFormControl();
formControl.InitialData = sArray[];
break;
case "下拉":
formControl = new DropDownFormControl();
formControl.InitialData = sArray[];
break;
case "自动":
formControl = new AutoCompleteFormControl();
formControl.InitialData = sArray[];
break;
default:
formControl = new UnknowFormControl();
break;
}
formControl.FieldName = sArray[];
formControl.ControlId = Guid.NewGuid(); }
else
{
formControl = FormControls.Single(f => f.ControlId == Guid.Parse(controlId));
switch (sArray[])
{
case "单行":
formControl.Width = int.Parse(sArray[]);
break;
case "多行":
formControl.Width = int.Parse(sArray[]);
formControl.Height = int.Parse(sArray[]);
break;
case "单选":
formControl.InitialData = sArray[];
break;
case "多选":
formControl.InitialData = sArray[];
break;
case "下拉":
formControl.InitialData = sArray[];
break;
case "自动":
formControl.InitialData = sArray[];
break;
default:
break;
}
} formControls.Add(formControl);
FormContent = FormContent.Replace(match.Value,
string.Format("{{{0}}}", formControl.ControlId));
} }
FormControls = formControls;
FormContent = FormContent;
}
} public string GetOccupyContentString()
{
var str = FormContent;
foreach (var formControl in FormControls)
{
str = str.Replace(string.Format("{{{0}}}", formControl.ControlId), formControl.GetDesignString());
}
return str;
} public string GetPreviewContentString()
{
var str = FormContent; foreach (var formControl in FormControls)
{
str = str.Replace(string.Format("{{{0}}}", formControl.ControlId), formControl.GetInputString());
}
return str;
} public string GetPreviewContentString(Dictionary<Guid, string> writedValues)
{
var str = FormContent; foreach (var formControl in FormControls)
{
string value = null;
if (writedValues != null && writedValues.TryGetValue(formControl.ControlId, out value))
{
str = str.Replace(string.Format("{{{0}}}", formControl.ControlId), value);
}
else
{
str = str.Replace(string.Format("{{{0}}}", formControl.ControlId), string.Empty);
}
}
return str;
} public string GetDisplayContent(List<Guid> canWriteformControlIds, SetAutoCompleteValue autoCompleteValue, Dictionary<Guid, string> writedValues = null)
{
var str = FormContent; foreach (var formControl in FormControls)
{
if (canWriteformControlIds.Contains(formControl.ControlId))
{
string value = null;
if (writedValues != null && writedValues.TryGetValue(formControl.ControlId, out value))
{
formControl.FieldValue = value;
}
if (string.IsNullOrEmpty(value) && formControl is AutoCompleteFormControl &&
!string.IsNullOrEmpty(formControl.InitialData) && autoCompleteValue != null)
{
formControl.FieldValue = autoCompleteValue(formControl.InitialData);
}
str = str.Replace(string.Format("{{{0}}}", formControl.ControlId), formControl.GetInputString());
}
else
{
string value = string.Empty;
if (writedValues != null && writedValues.TryGetValue(formControl.ControlId, out value))
{
formControl.FieldValue = value;
}
str = str.Replace(string.Format("{{{0}}}", formControl.ControlId), value);
}
}
return str;
}
}

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

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

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

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

FormControl类如下:

基类:

     [Serializable]
[XmlInclude(typeof(TextLineFormControl))]
[XmlInclude(typeof(MultiLineFormControl))]
[XmlInclude(typeof(RadioFormControl))]
[XmlInclude(typeof(CheckBoxFormControl))]
[XmlInclude(typeof(DropDownFormControl))]
[XmlInclude(typeof(AutoCompleteFormControl))]
[XmlInclude(typeof(UnknowFormControl))]
public abstract class FormControl
{
[XmlAttribute]
public Guid ControlId { get; set; }
[XmlAttribute]
public string FieldName { get; set; }
[XmlAttribute]
public string FieldValue { get; set; }
[XmlAttribute]
public int Width { get; set; }
[XmlAttribute]
public int Height { get; set; }
[XmlAttribute]
public string ToolTip { get; set; }
[XmlAttribute]
public bool Required { get; set; }
[XmlAttribute]
public bool CanWrite { get; set; }
[XmlAttribute]
public string InitialData { get; set; }
public abstract string GetDesignString();
public abstract string GetInputString();
}

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

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

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

几个派生类:

     [Serializable]
public class TextLineFormControl : FormControl
{
public override string GetDesignString()
{
return string.Format("<input type=\"text\" value=\"{0}//{1}//{2}\" style=\"{3}\" id=\"{4}\">",
WorkflowConstant.TextBoxFormControlName, FieldName, Width, WorkflowConstant.ControlDesignWidth,ControlId);
} public override string GetInputString()
{
return string.Format("<input type=\"text\" value=\"{0}\" id=\"{1}\" size=\"{2}\" maxlength=\"{2}\" name=\"{1}\" >",
FieldValue, ControlId, Width);
}
} [Serializable]
public class MultiLineFormControl : FormControl
{
public override string GetDesignString()
{
return string.Format("<input type=\"text\" value=\"{0}//{1}//{2}//{5}\" style=\"{3}\" id=\"{4}\">",
WorkflowConstant.TextAreaFormControlName, FieldName, Width, WorkflowConstant.ControlDesignWidth, ControlId, Height);
} public override string GetInputString()
{
return string.Format("<textarea cols=\"{2}\" rows=\"{3}\" id=\"{1}\" name=\"{1}\" >{0}</textarea>",
FieldValue != null ? FieldValue.Replace("<br/>", "\n\r") : string.Empty, ControlId, Width, Height);
}
} [Serializable]
public class RadioFormControl : FormControl
{
public override string GetDesignString()
{
return string.Format("<input type=\"text\" value=\"{0}//{1}//{2}\" style=\"{3}\" id=\"{4}\">",
WorkflowConstant.RadioFormControlName, FieldName, InitialData, WorkflowConstant.ControlDesignWidth, ControlId);
} public override string GetInputString()
{
StringBuilder sb= new StringBuilder();
var data = InitialData.Split('|');
for (int i = ; i < data.Length; i ++)
{
sb.AppendFormat("<input type=\"radio\" name=\"{0}\" id=\"{0}-{1}\" value=\"{2}\" {3}/>", ControlId, i,
data[i], FieldValue == data[i] ? " checked=\"checked\"" : string.Empty);
sb.AppendFormat("<label for=\"{0}-{1}\">{2}</label>", ControlId, i, data[i]);
}
return sb.ToString();
}
}
.........

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. MongoDB性能篇之创建索引,组合索引,唯一索引,删除索引和explain执行计划

    这篇文章主要介绍了MongoDB性能篇之创建索引,组合索引,唯一索引,删除索引和explain执行计划的相关资料,需要的朋友可以参考下 一.索引 MongoDB 提供了多样性的索引支持,索引信息被保存 ...

  2. HDU 1528 贪心模拟/二分图

    Card Game Cheater Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  3. JsonTest

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

  4. 【iCore3应用开发平台】发布 iCore3 应用开发平台使用说明

    PDF下载地址:http://pan.baidu.com/s/1c2ca2lU

  5. final阶段成员贡献分

    项目名:连连看 组名:天天向上 组长:王森 组员:张政.张金生.林莉.胡丽娜 final阶段各组员的贡献分分配如下: 姓名 个人工作量 组长评价 个人评价 团队贡献总分 张政 11 7 6 6.00 ...

  6. SQL UNION 和 UNION ALL 操作符\SQL SELECT INTO 语句\SQL CREATE DATABASE 语句

    SQL UNION 操作符 UNION 操作符用于合并两个或多个 SELECT 语句的结果集. 请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列.列也必须拥有相似的数据类型.同时,每 ...

  7. php数据优化

    Array ( [0] => Array ( [id] => 19 [receive_id] => 41 [mac] => a4:3d:78:fc:49:50 [staytim ...

  8. ansible 小试

    安装: pip install ansible 添加配置文件: 配置文件查找顺序 * ANSIBLE_CONFIG (环境变量) * ansible.cfg (当前目录下) * .ansible.cf ...

  9. Ionic2 开发环境搭建

    Ionic2开发环境要求: Nodejs V4.5.0 Nodejs自带 Npm V2.15.9 同上 Ionic V2.1.0 安装最新ionic即可 Angular2 V2正式版 同上 说明:以上 ...

  10. NSInternalInconsistencyException

    2016-09-10 12:48:13.281 Friend[92304:1843372] *** Terminating app due to uncaught exception 'NSInter ...