0
|
1 using System;
|
|
2 using System.Collections;
|
|
3 using System.Collections.Generic;
|
|
4 using System.ComponentModel;
|
|
5 using System.Drawing;
|
|
6 using System.Windows.Forms;
|
|
7 using Microsoft.Win32;
|
|
8
|
|
9 using BLToolkit.Validation;
|
|
10 using BLToolkit.Reflection;
|
|
11
|
|
12 using BLToolkit.Demo.ObjectModel;
|
|
13
|
|
14 namespace BLToolkit.Demo.Forms
|
|
15 {
|
|
16 public class BizEntityForm<F,T> : Form
|
|
17 where F : BizEntityForm<F,T>, new()
|
|
18 where T : BizEntity
|
|
19 {
|
|
20 #region Static Members
|
|
21
|
|
22 public static bool Edit(T entity, Action<T> saveAction)
|
|
23 {
|
|
24 T clone = (T)entity.Clone();
|
|
25 F form = new F();
|
|
26
|
|
27 form.SetBizEntity(clone);
|
|
28 form.Init(clone, delegate
|
|
29 {
|
|
30 saveAction(clone);
|
|
31
|
|
32 clone.CopyTo(entity);
|
|
33 entity.AcceptChanges();
|
|
34 });
|
|
35
|
|
36 return form.ShowDialog() == DialogResult.OK;
|
|
37 }
|
|
38
|
|
39 public static T EditNew(Action<T> saveAction)
|
|
40 {
|
|
41 T entity = TypeAccessor<T>.CreateInstanceEx();
|
|
42 F form = new F();
|
|
43
|
|
44 form.SetBizEntity(entity);
|
|
45 form.Init(entity, delegate
|
|
46 {
|
|
47 saveAction(entity);
|
|
48 entity.AcceptChanges();
|
|
49 });
|
|
50
|
|
51 return form.ShowDialog() == DialogResult.OK? entity: null;
|
|
52 }
|
|
53
|
|
54 private void Init(BizEntity entity, SaveHandler saveHandler)
|
|
55 {
|
|
56 if (AcceptButton is Button)
|
|
57 ((Button)AcceptButton).Click += SaveEntity;
|
|
58
|
|
59 _entity = entity;
|
|
60 _saveHandler = saveHandler;
|
|
61 }
|
|
62
|
|
63 #endregion
|
|
64
|
|
65 #region Abstracts
|
|
66
|
|
67 protected virtual void SetBizEntity(T entity)
|
|
68 {
|
|
69 throw new NotImplementedException();
|
|
70 }
|
|
71
|
|
72 #endregion
|
|
73
|
|
74 #region SaveEntity Handler
|
|
75
|
|
76 private delegate void SaveHandler();
|
|
77
|
|
78 private SaveHandler _saveHandler;
|
|
79 private BizEntity _entity;
|
|
80
|
|
81 protected void SaveEntity(object sender, EventArgs e)
|
|
82 {
|
|
83 if (_entity.IsDirty)
|
|
84 {
|
|
85 try
|
|
86 {
|
|
87 _entity.Validate();
|
|
88
|
|
89 UseWaitCursor = true;
|
|
90 _saveHandler();
|
|
91 UseWaitCursor = false;
|
|
92
|
|
93 DialogResult = DialogResult.OK;
|
|
94 Close();
|
|
95 }
|
|
96 catch (Exception ex)
|
|
97 {
|
|
98 UseWaitCursor = false;
|
|
99 MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
100 DialogResult = DialogResult.None;
|
|
101 }
|
|
102 }
|
|
103 else
|
|
104 {
|
|
105 DialogResult = DialogResult.Cancel;
|
|
106 Close();
|
|
107 }
|
|
108 }
|
|
109
|
|
110 #endregion
|
|
111
|
|
112 #region Scan Controls
|
|
113
|
|
114 private static void ForEach(Control control, Hashtable scanedControls, Predicate<Control> controlHandler)
|
|
115 {
|
|
116 if (control != null && !scanedControls.ContainsKey(control))
|
|
117 {
|
|
118 scanedControls.Add(control, control);
|
|
119
|
|
120 if (controlHandler(control))
|
|
121 foreach (Control c in control.Controls)
|
|
122 ForEach(c, scanedControls, controlHandler);
|
|
123 }
|
|
124 }
|
|
125
|
|
126 protected virtual void ScanControls(Predicate<Control> controlHandler)
|
|
127 {
|
|
128 ForEach(this, new Hashtable(), controlHandler);
|
|
129 }
|
|
130
|
|
131 protected virtual void ScanControls(Control control, Predicate<Control> controlHandler)
|
|
132 {
|
|
133 ForEach(control, new Hashtable(), controlHandler);
|
|
134 }
|
|
135
|
|
136 #endregion
|
|
137
|
|
138 #region OnLoad
|
|
139
|
|
140 protected override void OnLoad(EventArgs e)
|
|
141 {
|
|
142 base.OnLoad(e);
|
|
143
|
|
144 _toolTip.ToolTipIcon = ToolTipIcon.Warning;
|
|
145 _toolTip.ToolTipTitle = "Validation";
|
|
146
|
|
147 try
|
|
148 {
|
|
149 _toolTip.IsBalloon = (int)Registry.GetValue(
|
|
150 @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced",
|
|
151 "EnableBalloonTips", 1) != 0;
|
|
152 }
|
|
153 catch
|
|
154 {
|
|
155 }
|
|
156
|
|
157 if (!DesignMode)
|
|
158 {
|
|
159 ScanControls(InitBindableControls);
|
|
160 ValidateForm();
|
|
161 }
|
|
162 }
|
|
163
|
|
164 #endregion
|
|
165
|
|
166 #region Binding
|
|
167
|
|
168 class ControlInfo
|
|
169 {
|
|
170 public ControlInfo(Control control, bool isValidatable, PropertyDescriptor pd)
|
|
171 {
|
|
172 Control = control;
|
|
173 IsValidatable = isValidatable;
|
|
174 PropertyDescriptor = pd;
|
|
175 }
|
|
176
|
|
177 public Control Control;
|
|
178 public bool IsValidatable;
|
|
179 public PropertyDescriptor PropertyDescriptor;
|
|
180 }
|
|
181
|
|
182 ToolTip _toolTip = new ToolTip();
|
|
183
|
|
184 Dictionary<string, ControlInfo> _keyToControl = new Dictionary<string,ControlInfo>();
|
|
185 List<ControlInfo> _bindableControls = new List<ControlInfo>();
|
|
186
|
|
187 private bool InitBindableControls(Control control)
|
|
188 {
|
|
189 foreach (Binding binding in control.DataBindings)
|
|
190 {
|
|
191 BizEntity item = binding.BindingManagerBase.Current as BizEntity;
|
|
192
|
|
193 if (item != null)
|
|
194 {
|
|
195 string key = GetBindingKey(item, binding, control);
|
|
196
|
|
197 if (_keyToControl.ContainsKey(key))
|
|
198 continue;
|
|
199
|
|
200 string[] str = null;
|
|
201 PropertyDescriptor pd = null;
|
|
202
|
|
203 ITypedList typedList = binding.DataSource as ITypedList;
|
|
204
|
|
205 if (typedList != null)
|
|
206 {
|
|
207 pd = typedList.GetItemProperties(null).Find(
|
|
208 binding.BindingMemberInfo.BindingField, false);
|
|
209
|
|
210 if (pd != null)
|
|
211 str = Validator.GetErrorMessages(item, pd);
|
|
212 }
|
|
213
|
|
214 if (str == null)
|
|
215 str = item.GetErrorMessages(binding.BindingMemberInfo.BindingField);
|
|
216
|
|
217 if (str.Length > 0)
|
|
218 Array.Sort(str);
|
|
219
|
|
220 ControlInfo ci = new ControlInfo(control, str.Length > 0, pd);
|
|
221
|
|
222 _bindableControls.Add(ci);
|
|
223 _keyToControl.Add(key, ci);
|
|
224
|
|
225 if (ci.IsValidatable)
|
|
226 _toolTip.SetToolTip(control, string.Join("\r\n", str));
|
|
227
|
|
228 control.LostFocus += ValidateControl;
|
|
229 control.Validated += ValidateControl;
|
|
230 control.EnabledChanged += ValidateControl;
|
|
231 }
|
|
232 }
|
|
233
|
|
234 return true;
|
|
235 }
|
|
236
|
|
237 private void ValidateControl(object sender, EventArgs e)
|
|
238 {
|
|
239 Validate((Control)sender, true);
|
|
240 }
|
|
241
|
|
242 private static string GetBindingKey(BizEntity entity, Binding binding, Control control)
|
|
243 {
|
|
244 return string.Format("{0}.{1}.{2}",
|
|
245 entity.GetHashCode(), binding.BindingMemberInfo.BindingField, control.Name);
|
|
246 }
|
|
247
|
|
248 protected bool Validate(Control control, bool validateCombines)
|
|
249 {
|
|
250 bool result = true;
|
|
251
|
|
252 foreach (Binding binding in control.DataBindings)
|
|
253 {
|
|
254 if (binding.BindingManagerBase == null || binding.BindingManagerBase.Count == 0)
|
|
255 continue;
|
|
256
|
|
257 BizEntity item = binding.BindingManagerBase.Current as BizEntity;
|
|
258
|
|
259 if (item != null)
|
|
260 {
|
|
261 string key = GetBindingKey(item, binding, control);
|
|
262
|
|
263 if (!_keyToControl.ContainsKey(key))
|
|
264 continue;
|
|
265
|
|
266 ControlInfo ci = _keyToControl[key];
|
|
267 string fieldName = binding.BindingMemberInfo.BindingField;
|
|
268
|
|
269 bool isValid = ci.IsValidatable?
|
|
270 ci.PropertyDescriptor != null?
|
|
271 Validator.IsValid(item, ci.PropertyDescriptor):
|
|
272 item.IsValid(fieldName):
|
|
273 true;
|
|
274
|
|
275 if (isValid)
|
|
276 {
|
|
277 if (item.IsDirtyMember(fieldName))
|
|
278 SetDirty(control);
|
|
279 else
|
|
280 ResetControl(control);
|
|
281 }
|
|
282 else
|
|
283 {
|
|
284 SetInvalid(control);
|
|
285
|
|
286 result = false;
|
|
287 }
|
|
288
|
|
289 /*
|
|
290 if (validateCombines)
|
|
291 {
|
|
292 PropertyInfo pi =
|
|
293 item.GetType().GetProperty(binding.BindingMemberInfo.BindingField);
|
|
294
|
|
295 if (pi != null)
|
|
296 {
|
|
297 object[] attrs = pi.GetCustomAttributes(typeof(CombineAttribute), true);
|
|
298
|
|
299 foreach (CombineAttribute a in attrs)
|
|
300 {
|
|
301 string key = GetBindingKey(item, binding, control);
|
|
302 string key = item.GetHashCode() + "." + a.Name;
|
|
303
|
|
304 ControlInfo ci = (ControlInfo)nameToControl[key];
|
|
305
|
|
306 if (ci != null)
|
|
307 result = Validate(ci.Control, false) && result;
|
|
308 }
|
|
309 }
|
|
310 }
|
|
311 */
|
|
312 }
|
|
313 }
|
|
314
|
|
315 return result;
|
|
316 }
|
|
317
|
|
318 Dictionary<Control, Control> _modifiedControls = new Dictionary<Control,Control>();
|
|
319 Dictionary<Control, Color> _originalColors = new Dictionary<Control,Color>();
|
|
320
|
|
321 protected virtual void SetInvalid(Control control)
|
|
322 {
|
|
323 if (control.Enabled == false)
|
|
324 return;
|
|
325
|
|
326 if (_modifiedControls.ContainsKey(control) == false)
|
|
327 _modifiedControls.Add(control, control);
|
|
328
|
|
329 if (_originalColors.ContainsKey(control) == false)
|
|
330 _originalColors.Add(control, control.BackColor);
|
|
331
|
|
332 Color color = Modify((Color)_originalColors[control], 45, 0, 0);
|
|
333
|
|
334 if (color != control.BackColor)
|
|
335 control.BackColor = color;
|
|
336 }
|
|
337
|
|
338 protected virtual void SetDirty(Control control)
|
|
339 {
|
|
340 if (control.Enabled == false)
|
|
341 return;
|
|
342
|
|
343 if (_modifiedControls.ContainsKey(control) == false)
|
|
344 _modifiedControls.Add(control, control);
|
|
345
|
|
346 if (_originalColors.ContainsKey(control) == false)
|
|
347 _originalColors.Add(control, control.BackColor);
|
|
348
|
|
349 Color color = Modify((Color)_originalColors[control], 50, 50, -15);
|
|
350
|
|
351 if (color != control.BackColor)
|
|
352 control.BackColor = color;
|
|
353 }
|
|
354
|
|
355 protected virtual void ResetControl(Control control)
|
|
356 {
|
|
357 if (_modifiedControls.ContainsKey(control))
|
|
358 {
|
|
359 _modifiedControls.Remove(control);
|
|
360
|
|
361 if (_originalColors.ContainsKey(control))
|
|
362 {
|
|
363 control.BackColor = control.Enabled?
|
|
364 (Color)_originalColors[control]:
|
|
365 Color.FromKnownColor(KnownColor.Control);
|
|
366 }
|
|
367 }
|
|
368 }
|
|
369
|
|
370 public virtual bool ValidateForm()
|
|
371 {
|
|
372 bool isValid = true;
|
|
373
|
|
374 foreach (ControlInfo ci in _bindableControls)
|
|
375 isValid = Validate(ci.Control, false) && isValid;
|
|
376
|
|
377 return isValid;
|
|
378 }
|
|
379
|
|
380 public static Color Modify(Color original, int dr, int dg, int db)
|
|
381 {
|
|
382 int r = original.R + dr;
|
|
383 int g = original.G + dg;
|
|
384 int b = original.B + db;
|
|
385
|
|
386 if (r > 255 || g > 255 || b > 255)
|
|
387 {
|
|
388 int d = Math.Max(r, Math.Max(g, b)) - 255;
|
|
389
|
|
390 r -= d;
|
|
391 g -= d;
|
|
392 b -= d;
|
|
393 }
|
|
394
|
|
395 if (r < 0) r = 0;
|
|
396 if (g < 0) g = 0;
|
|
397 if (b < 0) b = 0;
|
|
398
|
|
399 return Color.FromArgb(r, g, b);
|
|
400 }
|
|
401
|
|
402 #endregion
|
|
403 }
|
|
404 }
|