InvokeHelper:多线程修改主界面控件属性并调用其中方法

挺不错的方法,先网摘过来留个记号http://blog.csdn.net/conmajia/article/details/7831251

/*******************************************************************************
 * InvokeHelper.cs
 * A thread-safe control invoker helper class.
 * -----------------------------------------------------------------------------
 * Project:Conmajia.Controls
 * Author:Conmajia
 * Url:[email protected]
 * History:
 *      4th Aug., 2012
 *      Added support for "Non-control" controls (such as ToolStripItem).
 *
 *      4th Aug., 2012
 *      Initiated.
 ******************************************************************************/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

namespace InvokerHelperDemo
{
    /// <summary>
    /// A thread-safe control invoker helper class.
    /// </summary>
    public class InvokeHelper
    {
        #region delegates
        private delegate object MethodInvoker(Control control, string methodName, params object[] args);

        private delegate object PropertyGetInvoker(Control control, object noncontrol, string propertyName);
        private delegate void PropertySetInvoker(Control control, object noncontrol, string propertyName, object value);
        #endregion

        #region static methods
        // helpers
        private static PropertyInfo GetPropertyInfo(Control control, object noncontrol, string propertyName)
        {
            if (control != null && !string.IsNullOrEmpty(propertyName))
            {
                PropertyInfo pi = null;
                Type t = null;

                if (noncontrol != null)
                    t = noncontrol.GetType();
                else
                    t = control.GetType();

                pi = t.GetProperty(propertyName);

                if (pi == null)
                    throw new InvalidOperationException(
                        string.Format(
                        "Can‘t find property {0} in {1}.",
                        propertyName,
                        t.ToString()
                        ));

                return pi;
            }
            else
                throw new ArgumentNullException("Invalid argument.");
        }

        // outlines
        public static object Invoke(Control control, string methodName, params object[] args)
        {
            if (control != null && !string.IsNullOrEmpty(methodName))
                if (control.InvokeRequired)
                    return control.Invoke(
                        new MethodInvoker(Invoke),
                        control,
                        methodName,
                        args
                        );
                else
                {
                    MethodInfo mi = null;

                    if (args != null && args.Length > 0)
                    {
                        Type[] types = new Type[args.Length];
                        for (int i = 0; i < args.Length; i++)
                        {
                            if (args[i] != null)
                                types[i] = args[i].GetType();
                        }

                        mi = control.GetType().GetMethod(methodName, types);
                    }
                    else
                        mi = control.GetType().GetMethod(methodName);

                    // check method info you get
                    if (mi != null)
                        return mi.Invoke(control, args);
                    else
                        throw new InvalidOperationException("Invalid method.");
                }
            else
                throw new ArgumentNullException("Invalid argument.");
        }

        public static object Get(Control control, string propertyName)
        {
            return Get(control, null, propertyName);
        }
        public static object Get(Control control, object noncontrol, string propertyName)
        {
            if (control != null && !string.IsNullOrEmpty(propertyName))
                if (control.InvokeRequired)
                    return control.Invoke(new PropertyGetInvoker(Get),
                        control,
                        noncontrol,
                        propertyName
                        );
                else
                {
                    PropertyInfo pi = GetPropertyInfo(control, noncontrol, propertyName);
                    object invokee = (noncontrol == null) ? control : noncontrol;

                    if (pi != null)
                        if (pi.CanRead)
                            return pi.GetValue(invokee, null);
                        else
                            throw new FieldAccessException(
                                string.Format(
                                "{0}.{1} is a write-only property.",
                                invokee.GetType().ToString(),
                                propertyName
                                ));

                    return null;
                }
            else
                throw new ArgumentNullException("Invalid argument.");
        }

        public static void Set(Control control, string propertyName, object value)
        {
            Set(control, null, propertyName, value);
        }
        public static void Set(Control control, object noncontrol, string propertyName, object value)
        {
            if (control != null && !string.IsNullOrEmpty(propertyName))
                if (control.InvokeRequired)
                    control.Invoke(new PropertySetInvoker(Set),
                        control,
                        noncontrol,
                        propertyName,
                        value
                        );
                else
                {
                    PropertyInfo pi = GetPropertyInfo(control, noncontrol, propertyName);
                    object invokee = (noncontrol == null) ? control : noncontrol;

                    if (pi != null)
                        if (pi.CanWrite)
                            pi.SetValue(invokee, value, null);
                        else
                            throw new FieldAccessException(
                                string.Format(
                                "{0}.{1} is a read-only property.",
                                invokee.GetType().ToString(),
                                propertyName
                                ));
                }
            else
                throw new ArgumentNullException("Invalid argument.");
        }
        #endregion
    }
}
时间: 2024-08-05 07:02:43

InvokeHelper:多线程修改主界面控件属性并调用其中方法的相关文章

WPF编程,通过【帧】动态更改控件属性的一种方法。

原文:WPF编程,通过[帧]动态更改控件属性的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details/87249998 WPF提供了一种基于帧的动画实现方式,由CompositionTarget类来完成. WPF会在每次界面刷新时调用该回调函数. CompositionTarget的刷新率与窗体保持一致,因此很难人工控制动画的快慢. ?1.前台 <Grid> <Grid.RowDefin

WPF编程,通过Double Animation动态更改控件属性的一种方法。

原文:WPF编程,通过Double Animation动态更改控件属性的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details/87251422 DoubleAnimation类指定起始值(From="30").终点值(To="300").时间(Duration="3"),以及动画结束应该如何(FillBehavior="Stop&qu

日积(Running)月累(ZSSURE):WCF学习之“通过事件绑定控制WinForm宿主程序主界面控件”

背景: WCF服务需要寄宿到相应的可运行进程中执行,常见的有四种寄宿,分别是控制台程序.WinForm程序.IIS和Windows服务.之前学习老A博客和<WCF全面解析>时最常用到的是控制台寄宿,近期由于项目需求,需要在WinForm程序中调用WCF服务,本博文通过一个简单的实例来演示WCF在WinForm中的寄宿.并着重介绍如何利用事件绑定控制宿主主UI界面控件. 题记: 之前一直坚守在C++阵地,对于新语言.新技术(诸如Python.J2EE.Bigdata.AI)不甚感冒.自以为&qu

【转】VC 多线程中控制界面控件的几种方法

原文网址:https://software.intel.com/zh-cn/blogs/2010/11/30/vc-3 为了保证界面的用户体验经常要把数据处理等放到子线程中进行,然后把结果更新到主界面,通常有这样几种方法. 1. 启动线程时把控件关联变量的指针传参给线程函数,这种方法无疑是最简单的方法,但极容易造成访问异常,因为VC6中的控件都不是线程安全的. 2. 就是先进一点的方法,把控件的句柄传给线程函数,有时也不好用在子线程中通过SendNotifyMessage or PostMess

C# 的界面控件属性修改线程安全问题

今天在实验delegate与thread 在初步的实验结束后,因为原来的delegate只有一个函数会被调用,感觉没有达到delegate的极致,所以又重新自己定义了一个delegate,在另一个线程 运行时调用这个delegate,其中有两个函数会被顺序调用. 一开始写的很顺利,点击运行.生成第二个线程后,突然报出异常.说是不能再控件创建的线程外调用这个控件的属性. 于是有些奇怪,因为只是加入了一个不痛不痒的函数而已. 回溯,发现问题. 原来原来调用delegate,是通过控件的invoke方

多线程环境的UI控件属性更新

Winform: public delegate void UpadataTextCallBack(string str,TextBox text); public void UpadtaText(string str, TextBox text) { if (text.InvokeRequired) { UpadataTextCallBack upadataTextCallBack = UpadtaText; text.Invoke(upadataTextCallBack, new objec

C++MFC编程笔记day10 MF界面控件的使用2、属性页对话框、MFC线程

一 树型控件 1 相关类 CTreeCtrl-父类是CWnd,控件类. CTreeView-父类是CCtrlView,视图类.CTreeView=CView+CTreeCtrl CTreeView::GetTreeCtrl 2 CTreeCtrl的使用 对比CListCtrl:列表控件的每个数据项之间是平等关系,通过数据项 的索引值得到数据项的信息.树控件每个数据项称之为节点.节点之间 的关系包括父子关系和兄弟关系.通常通过节点句柄得到某个节点. 通常用来表示层次关系的数据. 2.1 设置控件的

基于MVC4+EasyUI的Web开发框架形成之旅--界面控件的使用

在前面介绍了两篇关于我的基于MVC4+EasyUI技术的Web开发框架的随笔,本篇继续介绍其中界面部分的一些使用知识,包括控件的赋值.取值.清空,以及相关的使用. 我们知道,一般Web界面包括的界面控件有:单行文本框.多行文本框.密码文本框.下拉列表Combobox.日期输入控件.数值输入控件.单项选择.复选框.表格控件DataGrid.树形控件.布局控件.弹出式对话框.提示信息.列表控件等,这些界面控件的操作都有哪些不同,下面我们来逐一进行介绍. <input class="easyui

UITextField控件属性

UITextField控件属性: enablesReturnKeyAutomatically 默认为No,如果设置为Yes,文本框中没有输入任何字符的话,右下角的返回按钮是disabled的. 1.borderStyle 设置边框样式,只有设置了才会显示边框样式 text.borderStyle = UITextBorderStyleRoundedRect; typedef enum { UITextBorderStyleNone, UITextBorderStyleLine, UITextBo