Invoke和BeginInvoke 在Winform 中更新控件的用法说明

WPF 程序出现:

参数计数不匹配,未处理System.Reflection.TargetParameterCountException
解决方法引用http://www.cnblogs.com/wene/p/4668830.html
根据调试的实际情况显示, 委托出现问题,此异常是在使用Invoke调用时, 没有正确匹配参数数量,因为Invoke或BeginInvoke方法的参数数量是可变的,所以在编译阶段根本不会出现编译错误,但在程序正式执行时,又要求目标调用方法与Delegate的方法定义必须一致,如不一致,则会出现如上异常信息。
最后检查的确是委托参数传入个数不对!!!
 
 
WPF 委托用法:
在DelegateState类声明
public delegate void ChartCallBack(object cht, List data);
public static ChartCallBack ChtInfo;
 
在调用地方:
1.初始化:DelegateState.ChtInfo = chtShow;
 
2.编写函数实体:private void chtShow(object ch, List data)
        {
            Chart cht = ch as Chart;
 
            this.Dispatcher.Invoke(new DelegateState.ChartCallBack(delegate
            {
                //函数实现在这
                }
            }), new object[] { ch, data});
        }
3.要用的地方调用:DelegateState.ChtInfo ((object)chart, (List)data);
需要注意的地方:WFP 里面委托调用时,控件只能以object形式传进去,所以先强制转换为object,然后在委托函数实体部分再强制转换为所需要的控件。
 
Winform 委托方法:
声明一致,在调用方面有不同。
在调用地方:
1.初始化:DelegateState.ChtInfo = chtShow;
 
2.编写函数实体:
        void chtShow(object chart ,List data)
        {
            
                this.Invoke(new ThreadStart(delegate
                {
                   //函数实现在这
                    }
                }));
或者下面一种写法也是可以的
this.Invoke(new DelegateState.ChartCallBack(delegate
            {
                //函数实现在这
                }
            }), new object[] { ch, data});
        }
3.要用的地方调用:DelegateState.ChtInfo ((object)chart, (List)data);
在winform里面用的是  this.Invoke,而WPF是  this.Dispatcher.Invoke,调用传入参数可以直接是控件

转载于:https://www.cnblogs.com/JianGuoWan/p/9148129.html

当你在WinForm项目遇到这个错误:“在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke”,这是因为试图在控件尚未完全初始化或显示出来的时候就操作它们引发的。`Invoke` 和 `BeginInvoke` 是用于在UI线程外更新控件的方法,但是为了保证线程安全和UI响应,这些操作需要在控件已经添加到窗体并有了窗口句柄之后才能执行。 解决这个问题的方法有几种: 1. **确保调用时间**:检查你的代码,确认是否在控件的构造函数、Load事件或其他早期处理阶段尝试了`Invoke`或`BeginInvoke`。应该在控件加载完成后执行这类操作。 ```csharp private void Form1_Load(object sender, EventArgs e) { // 这可以安全地调用 Invoke 或 BeginInvoke this.Invoke(new Action(() => YourMethodThatNeedsToBeInvoked())); } ``` 2. **异步等待**:如果你的操作是可延后的,考虑将它放入一个异步任务,并在适当的时机(如`OnHandleCreated`事件)启动该任务。 ```csharp private async Task InitializeTask() { await Task.Delay(1); // 等待控件加载完成 // 现在可以安全地调用 await YourAsyncOperation(); } public partial class Form1 : Form { protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); InitializeTask().ConfigureAwait(false); // 启动任务 } } ``` 3. **事件订阅**:如果是在某个事件触发时需要操作控件,可以在事件处理器内部调用。 ```csharp button.Click += (sender, e) => { if (this.IsHandleCreated) { // 控制在此处是可用的 UpdateControls(); } else { // 如果尚未创建句柄,延迟处理 Invoke((Action)(() => UpdateControls())); } }; private void UpdateControls() { // 更新控件内容... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值