comparison Demo/WinForms/Forms/BizEntityForm.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f990fcb411a9
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 }