//==============================================================
//  版权所有：深圳杰文科技
//  文件名：ControlUtil.cs
//  版本：V1.0  
//  创建者：Jay  ( QQ： 85363208 )
//  创建时间：2017-11-28 16:18
//  创建描述：
//  修改者：
//  修改时间：
//  修改说明： 
//==============================================================

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Grid;

namespace Infrastructure.Components
{
	/// <summary>
	/// 提供常用的操作控件的方法
	/// </summary>
	public static class ControlUtil
	{
		/// <summary>
		/// 判断控件是否处于设计模式下。
		/// </summary>
		public static bool IsDesignMode(Control control)
		{
			System.Type t = typeof(System.ComponentModel.Component);
			System.Reflection.PropertyInfo pi = t.GetProperty("DesignMode", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
			do
			{
				if ((bool)pi.GetValue(control, null))
				{
					return true;
				}
				control = control.Parent;
			} while (control != null);

			return false;
		}

		/// <summary>
		/// 设置一个控件（容器）以及它的子控件为只读。
		/// </summary>
		/// <param name="parentControl"></param>
		/// <param name="readOnly"></param>
		public static void SetControls(Control parentControl, bool readOnly)
		{
			foreach (Control c in parentControl.Controls)
			{
				if (c is BaseEdit)
				{
					(c as BaseEdit).Properties.ReadOnly = readOnly;
					if (c is ButtonEdit)
					{
						ButtonEdit button = c as ButtonEdit;
						if (button.Properties.Buttons.Count > 0)
						{
							button.Properties.Buttons[0].Enabled = !readOnly;
						}
					}
				}
				else
				{
					SetControls(c, readOnly);
				}
			}
		}

		#region 将焦点定位到与指定实体类属性绑定的控件上

		/// <summary>
		/// 将焦点定位到与指定实体类属性绑定的子控件上
		/// </summary>
		/// <param name="controls">控件的集合</param>
		/// <param name="property">实体类的属性</param>
		public static Control Focus(Control container, string property)
		{
			List<Control> lst = new List<Control>();
			FindChildren(container.Controls, lst);

			foreach (Control ctl in lst)
			{
				foreach (Binding bd in ctl.DataBindings)
				{
					if (object.Equals(bd.BindingMemberInfo.BindingField, property))
					{
						ctl.Focus();
						return ctl;
					}
				}
			}

			return null;
		}


		/// <summary>
		/// 将焦点定位到与指定实体类属性绑定的子控件上
		/// </summary>
		/// <param name="controls">控件的集合</param>
		/// <param name="datasource">绑定的实体类</param>
		/// <param name="property">实体类的属性</param>
		public static Control Focus(Control container, object datasource, string property)
		{
			List<Control> lst = new List<Control>();
			FindChildren(container.Controls, lst);

			foreach (Control ctl in lst)
			{
				if (ctl.DataBindings.Count == 0)
					continue;

				foreach (Binding bd in ctl.DataBindings)
				{

					if (object.ReferenceEquals(bd.DataSource, datasource)
						|| (bd.BindingManagerBase.Position >= 0
							&& object.ReferenceEquals(bd.BindingManagerBase.Current, datasource))
						)
					{
						if (object.Equals(bd.BindingMemberInfo.BindingField, property))
						{
							ctl.Focus();
							return ctl;
						}
					}
				}
			}

			return null;
		}


		#endregion

		#region 查找所有的子控件

		/// <summary>
		/// 递归查找所有子控件
		/// </summary>
		public static List<Control> FindChildren(IEnumerable parentControls, List<Control> childControlList)
		{
			foreach (Control obj in parentControls)
			{
				childControlList.Add(obj);
				FindChildren(obj.Controls, childControlList);
			}
			return childControlList;
		}

		public static void FindChildren<T>(Control parentControl, List<T> childControlList) where T : Control
		{
			foreach (Control control in parentControl.Controls)
			{
				if (control is T)
				{
					childControlList.Add((T)control);
				}
				FindChildren(control, childControlList);
			}
		}

		#endregion

		#region CreateControl、GetControl

		//生成指定类型的控件，并以填满的方式放在父控件中
		public static T CreateControl<T>(Control parentControl)
		{
			T t = Activator.CreateInstance<T>();
			Control control = t as Control;
			parentControl.Controls.Add(control);
			control.Dock = DockStyle.Fill;
			return t;
		}

		//获取父控件中的指定类型的控件
		//注意，T必须从Control继承
		public static T GetControl<T>(Control parentControl) where T : Control
		{
			foreach (Control c in parentControl.Controls)
			{
				if (c is T)
				{
					return c as T;
				}
			}
			return default(T);
		}

		#endregion

		/// <summary>
		/// 延时100毫秒后调用。处理完当前事件后再调用某段逻辑。
		/// <param name="method">延时执行的逻辑代码段</param>
		/// </summary>
		public static void PostInvoke(Control ctl, MethodInvoker method)
		{
			PostInvoke(ctl, method, 100);
		}

		/// <summary>
		/// 延时调用。处理完当前事件后再调用某段逻辑。
		/// <param name="method">延时执行的逻辑代码段</param>
		/// <param name="millis">延迟的毫秒数</param>
		/// </summary>
		public static void PostInvoke(Control ctl, MethodInvoker method, int millis)
		{
			ThreadPool.QueueUserWorkItem(delegate(object state)
			{
				if (millis > 0)
					Thread.Sleep(millis);

				if (!ctl.IsDisposed || ctl.Disposing)
				{
					try
					{
						ctl.Invoke((MethodInvoker)delegate
						{
							method.Invoke();
						});
					}
					catch (Exception e)
					{
						Debug.WriteLine(e.Message);
					}
				}
			}, null);

		}
	}
}
