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
+	}
+}