Mercurial > pub > bltoolkit
diff Demo/WinForms/Forms/BizEntityForm.cs @ 0:f990fcb411a9
Копия текущей версии из github
author | cin |
---|---|
date | Thu, 27 Mar 2014 21:46:09 +0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Demo/WinForms/Forms/BizEntityForm.cs Thu Mar 27 21:46:09 2014 +0400 @@ -0,0 +1,404 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; +using Microsoft.Win32; + +using BLToolkit.Validation; +using BLToolkit.Reflection; + +using BLToolkit.Demo.ObjectModel; + +namespace BLToolkit.Demo.Forms +{ + public class BizEntityForm<F,T> : Form + where F : BizEntityForm<F,T>, new() + where T : BizEntity + { + #region Static Members + + public static bool Edit(T entity, Action<T> saveAction) + { + T clone = (T)entity.Clone(); + F form = new F(); + + form.SetBizEntity(clone); + form.Init(clone, delegate + { + saveAction(clone); + + clone.CopyTo(entity); + entity.AcceptChanges(); + }); + + return form.ShowDialog() == DialogResult.OK; + } + + public static T EditNew(Action<T> saveAction) + { + T entity = TypeAccessor<T>.CreateInstanceEx(); + F form = new F(); + + form.SetBizEntity(entity); + form.Init(entity, delegate + { + saveAction(entity); + entity.AcceptChanges(); + }); + + return form.ShowDialog() == DialogResult.OK? entity: null; + } + + private void Init(BizEntity entity, SaveHandler saveHandler) + { + if (AcceptButton is Button) + ((Button)AcceptButton).Click += SaveEntity; + + _entity = entity; + _saveHandler = saveHandler; + } + + #endregion + + #region Abstracts + + protected virtual void SetBizEntity(T entity) + { + throw new NotImplementedException(); + } + + #endregion + + #region SaveEntity Handler + + private delegate void SaveHandler(); + + private SaveHandler _saveHandler; + private BizEntity _entity; + + protected void SaveEntity(object sender, EventArgs e) + { + if (_entity.IsDirty) + { + try + { + _entity.Validate(); + + UseWaitCursor = true; + _saveHandler(); + UseWaitCursor = false; + + DialogResult = DialogResult.OK; + Close(); + } + catch (Exception ex) + { + UseWaitCursor = false; + MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + DialogResult = DialogResult.None; + } + } + else + { + DialogResult = DialogResult.Cancel; + Close(); + } + } + + #endregion + + #region Scan Controls + + private static void ForEach(Control control, Hashtable scanedControls, Predicate<Control> controlHandler) + { + if (control != null && !scanedControls.ContainsKey(control)) + { + scanedControls.Add(control, control); + + if (controlHandler(control)) + foreach (Control c in control.Controls) + ForEach(c, scanedControls, controlHandler); + } + } + + protected virtual void ScanControls(Predicate<Control> controlHandler) + { + ForEach(this, new Hashtable(), controlHandler); + } + + protected virtual void ScanControls(Control control, Predicate<Control> controlHandler) + { + ForEach(control, new Hashtable(), controlHandler); + } + + #endregion + + #region OnLoad + + protected override void OnLoad(EventArgs e) + { + base.OnLoad(e); + + _toolTip.ToolTipIcon = ToolTipIcon.Warning; + _toolTip.ToolTipTitle = "Validation"; + + try + { + _toolTip.IsBalloon = (int)Registry.GetValue( + @"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced", + "EnableBalloonTips", 1) != 0; + } + catch + { + } + + if (!DesignMode) + { + ScanControls(InitBindableControls); + ValidateForm(); + } + } + + #endregion + + #region Binding + + class ControlInfo + { + public ControlInfo(Control control, bool isValidatable, PropertyDescriptor pd) + { + Control = control; + IsValidatable = isValidatable; + PropertyDescriptor = pd; + } + + public Control Control; + public bool IsValidatable; + public PropertyDescriptor PropertyDescriptor; + } + + ToolTip _toolTip = new ToolTip(); + + Dictionary<string, ControlInfo> _keyToControl = new Dictionary<string,ControlInfo>(); + List<ControlInfo> _bindableControls = new List<ControlInfo>(); + + private bool InitBindableControls(Control control) + { + foreach (Binding binding in control.DataBindings) + { + BizEntity item = binding.BindingManagerBase.Current as BizEntity; + + if (item != null) + { + string key = GetBindingKey(item, binding, control); + + if (_keyToControl.ContainsKey(key)) + continue; + + string[] str = null; + PropertyDescriptor pd = null; + + ITypedList typedList = binding.DataSource as ITypedList; + + if (typedList != null) + { + pd = typedList.GetItemProperties(null).Find( + binding.BindingMemberInfo.BindingField, false); + + if (pd != null) + str = Validator.GetErrorMessages(item, pd); + } + + if (str == null) + str = item.GetErrorMessages(binding.BindingMemberInfo.BindingField); + + if (str.Length > 0) + Array.Sort(str); + + ControlInfo ci = new ControlInfo(control, str.Length > 0, pd); + + _bindableControls.Add(ci); + _keyToControl.Add(key, ci); + + if (ci.IsValidatable) + _toolTip.SetToolTip(control, string.Join("\r\n", str)); + + control.LostFocus += ValidateControl; + control.Validated += ValidateControl; + control.EnabledChanged += ValidateControl; + } + } + + return true; + } + + private void ValidateControl(object sender, EventArgs e) + { + Validate((Control)sender, true); + } + + private static string GetBindingKey(BizEntity entity, Binding binding, Control control) + { + return string.Format("{0}.{1}.{2}", + entity.GetHashCode(), binding.BindingMemberInfo.BindingField, control.Name); + } + + protected bool Validate(Control control, bool validateCombines) + { + bool result = true; + + foreach (Binding binding in control.DataBindings) + { + if (binding.BindingManagerBase == null || binding.BindingManagerBase.Count == 0) + continue; + + BizEntity item = binding.BindingManagerBase.Current as BizEntity; + + if (item != null) + { + string key = GetBindingKey(item, binding, control); + + if (!_keyToControl.ContainsKey(key)) + continue; + + ControlInfo ci = _keyToControl[key]; + string fieldName = binding.BindingMemberInfo.BindingField; + + bool isValid = ci.IsValidatable? + ci.PropertyDescriptor != null? + Validator.IsValid(item, ci.PropertyDescriptor): + item.IsValid(fieldName): + true; + + if (isValid) + { + if (item.IsDirtyMember(fieldName)) + SetDirty(control); + else + ResetControl(control); + } + else + { + SetInvalid(control); + + result = false; + } + + /* + if (validateCombines) + { + PropertyInfo pi = + item.GetType().GetProperty(binding.BindingMemberInfo.BindingField); + + if (pi != null) + { + object[] attrs = pi.GetCustomAttributes(typeof(CombineAttribute), true); + + foreach (CombineAttribute a in attrs) + { + string key = GetBindingKey(item, binding, control); + string key = item.GetHashCode() + "." + a.Name; + + ControlInfo ci = (ControlInfo)nameToControl[key]; + + if (ci != null) + result = Validate(ci.Control, false) && result; + } + } + } + */ + } + } + + return result; + } + + Dictionary<Control, Control> _modifiedControls = new Dictionary<Control,Control>(); + Dictionary<Control, Color> _originalColors = new Dictionary<Control,Color>(); + + protected virtual void SetInvalid(Control control) + { + if (control.Enabled == false) + return; + + if (_modifiedControls.ContainsKey(control) == false) + _modifiedControls.Add(control, control); + + if (_originalColors.ContainsKey(control) == false) + _originalColors.Add(control, control.BackColor); + + Color color = Modify((Color)_originalColors[control], 45, 0, 0); + + if (color != control.BackColor) + control.BackColor = color; + } + + protected virtual void SetDirty(Control control) + { + if (control.Enabled == false) + return; + + if (_modifiedControls.ContainsKey(control) == false) + _modifiedControls.Add(control, control); + + if (_originalColors.ContainsKey(control) == false) + _originalColors.Add(control, control.BackColor); + + Color color = Modify((Color)_originalColors[control], 50, 50, -15); + + if (color != control.BackColor) + control.BackColor = color; + } + + protected virtual void ResetControl(Control control) + { + if (_modifiedControls.ContainsKey(control)) + { + _modifiedControls.Remove(control); + + if (_originalColors.ContainsKey(control)) + { + control.BackColor = control.Enabled? + (Color)_originalColors[control]: + Color.FromKnownColor(KnownColor.Control); + } + } + } + + public virtual bool ValidateForm() + { + bool isValid = true; + + foreach (ControlInfo ci in _bindableControls) + isValid = Validate(ci.Control, false) && isValid; + + return isValid; + } + + public static Color Modify(Color original, int dr, int dg, int db) + { + int r = original.R + dr; + int g = original.G + dg; + int b = original.B + db; + + if (r > 255 || g > 255 || b > 255) + { + int d = Math.Max(r, Math.Max(g, b)) - 255; + + r -= d; + g -= d; + b -= d; + } + + if (r < 0) r = 0; + if (g < 0) g = 0; + if (b < 0) b = 0; + + return Color.FromArgb(r, g, b); + } + + #endregion + } +}