using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Windows.Forms;namespace Extension.MyDll
{/// <summary>/// 辅助类:跨线程更新控件/// </summary>public class MyInvokHelper{#region 委托/// <summary>/// 执行控件对象方法的委托/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="methodName">方法名称</param>/// <param name="args">方法的参数列表</param>/// <returns></returns>private delegate object MethodInvoker(Control control, string methodName, params object[] args);/// <summary>/// 获取对象属性值的委托/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="noneControl">非控件对象的引用</param>/// <param name="propertyName">属性名称</param>/// <returns></returns>private delegate object PropertyGetInvoker(Control control, object noneControl, string propertyName);/// <summary>/// 设置对象属性值的委托/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="noneControl">非控件对象的引用</param>/// <param name="propertyName">属性名称</param>/// <param name="value">属性设置值</param>private delegate void PropertySetInvoker(Control control, object noneControl, string propertyName, object value);#endregion#region 方法/// <summary>/// 获取对象指定名称的属性值/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="noneControl">非控件对象的引用</param>/// <param name="propertyName">属性名称</param>/// <returns></returns>private static PropertyInfo GetPropertyInfo(Control control, object noneControl, string propertyName){if ((control != null || noneControl != null) && !string.IsNullOrEmpty(propertyName)){object obj = noneControl != null ? noneControl : control;Type type = obj.GetType();PropertyInfo pi = type.GetProperty(propertyName); //获取对应名称的属性值,未找到返回nullif (pi == null){//未找到对应名称的属性throw new InvalidOperationException(string.Format("Can't find property {0} in {1}.", propertyName, type.ToString()));}else{//找到对应名称的属性return pi;}}else{throw new ArgumentNullException("Invaild argument.");}}/// <summary>/// 执行控件对象指定名称的方法(InvokeMethod方法仅针对控件,非控件无Invoke方法)/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="methodName">方法名称</param>/// <param name="args">方法的参数列表</param>/// <returns></returns>public static object InvokeMethod(Control control, string methodName, params object[] args){if (control != null && !string.IsNullOrEmpty(methodName)){if (control.InvokeRequired){//从创建控件的线程以外访问控件return control.Invoke(new MethodInvoker(InvokeMethod), new object[] { control, methodName, args });}else{MethodInfo mi = null;bool argsIsNullFlag = true;if (args != null && args.Length > 0){argsIsNullFlag = false;Type[] types = new Type[args.Length];for (int i = 0; i < args.Length; i++){types[i] = args[i] != null ? args[i].GetType() : null;}mi = control.GetType().GetMethod(methodName, types); //匹配带参方法}else{argsIsNullFlag = true;mi = control.GetType().GetMethod(methodName); //匹配无参方法}if (mi != null){return mi.Invoke(control, argsIsNullFlag ? null : args);}else{throw new InvalidOperationException("Invalid method.");}}}else{throw new ArgumentNullException("Invalid argument.");}}/// <summary>/// 获取对象指定名称的属性值/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="noneControl">非控件对象的引用</param>/// <param name="propertyName">属性名称</param>/// <returns></returns>public static object GetProperty(Control control, object noneControl, string propertyName){if ((control != null || noneControl != null) && !string.IsNullOrEmpty(propertyName)){if (control != null && control.InvokeRequired){return control.Invoke(new PropertyGetInvoker(GetProperty), new object[] { control, noneControl, propertyName });}else{PropertyInfo pi = GetPropertyInfo(control, noneControl, propertyName);object invoke = (noneControl == null) ? control : noneControl;if (pi != null){if (pi.CanRead){return pi.GetValue(invoke);}else{throw new FieldAccessException(string.Format("{0}.{1} is a write-only property.", invoke.GetType().ToString(), propertyName));}}else{return null;}}}else{throw new ArgumentNullException("Invalid argument.");}}/// <summary>/// GetProperty方法的重载,获取控件对象指定名称的属性值/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="propertyName">属性名称</param>/// <returns></returns>public static object GetProperty(Control control, string propertyName){return GetProperty(control, null, propertyName);}/// <summary>/// 设置对象指定名称的属性值/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="noneControl">非控件对象的引用</param>/// <param name="propertyName">属性名称</param>/// <param name="value">属性设置值</param>/// <returns></returns>public static void SetProperty(Control control, object noneControl, string propertyName, object value){if ((control != null || noneControl != null) && !string.IsNullOrEmpty(propertyName)){if (control != null && control.InvokeRequired){control.Invoke(new PropertySetInvoker(SetProperty), new object[] { control, noneControl, propertyName, value });}else{PropertyInfo pi = GetPropertyInfo(control, noneControl, propertyName);object invoke = (noneControl == null) ? control : noneControl;if (pi != null){if (pi.CanWrite){pi.SetValue(invoke, value);}else{throw new FieldAccessException(string.Format("{0}.{1} is a read-only property.", invoke.GetType().ToString(), propertyName));}}}}else{throw new ArgumentNullException("Invalid argument.");}}/// <summary>/// SetProperty方法的重载,设置控件对象指定名称的属性值/// </summary>/// <param name="control"></param>/// <param name="propertyName"></param>/// <param name="value"></param>public static void SetProperty(Control control, string propertyName, object value){SetProperty(control, null, propertyName, value);}#endregion}
}