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