在非UI线程中改变UI控件属性的通用方法
2010-10-10 14:23
471 查看
转自:http://www.sunnychen.org/trackback.asp?tbID=124&action=addtb&tbKey=43c0d85c8d6d5dcc018d174276ac098da9245500
在.NET中如需在非UI线程中改变UI控件属性时,CLR会抛出异常,提示无法在非UI线程中更新界面上的控件(Cross-threadoperationnotvalid)。一般情况下有两种解决办法。第一种就是设置Control的静态属性CheckForIllegalCrossThreadCalls为False,如下:
另一种办法,就是使用委托,根据控件的InvokeRequired属性判断当前控件的更新操作是否是在另一个线程中。如果是,则使用委托进行方法调用并更新控件。但是这种方法有个缺点,就是需要针对每个控件的属性设置方式创建一些单独的委托和方法,这些委托和方法仅仅是在解决跨线程操作的时候使用。比如,你在另一个线程中需要修改某个label的text时,你就需要创建一个SetLabelText方法,假设你还需要更新TextBox的text,那么你还需要另外创建一个SetTextBoxText方法。
通过下面的委托和方法的定义,我们实现了“一次定义,多次使用”。请看:
viewsource
print?
于是,上面的例子可以改为:
viewsource
print?
在.NET中如需在非UI线程中改变UI控件属性时,CLR会抛出异常,提示无法在非UI线程中更新界面上的控件(Cross-threadoperationnotvalid)。一般情况下有两种解决办法。第一种就是设置Control的静态属性CheckForIllegalCrossThreadCalls为False,如下:
01 | public Form1() |
02 | { |
03 | InitializeComponent(); |
04 | Control.CheckForIllegalCrossThreadCalls= false ; |
05 | } |
06 |
07 | private void button1_Click( object sender,EventArgse) |
08 | { |
09 | Threadthread= new Thread(()=> |
10 | { |
11 | for ( int i=0;i<100000;i++) |
12 | { |
13 | label1.Text=i.ToString(); |
14 | label1.Refresh(); |
15 | } |
16 | }); |
17 | thread.Start(); |
18 | } |
通过下面的委托和方法的定义,我们实现了“一次定义,多次使用”。请看:
01 | private delegate void ParameterizedControlUpdate( params object []args); |
02 |
03 | private delegate void ControlUpdateDelegate(Componentc, |
04 | ParameterizedControlUpdatecallback, |
05 | params object []args); |
06 |
07 | private void DelegatedControlUpdate(Componentc, |
08 | ParameterizedControlUpdatecallback, |
09 | params object []args) |
10 | { |
11 | Controltarget=(c is Control)?(c as Control): this ; |
12 | if (target.InvokeRequired) |
13 | { |
14 | ControlUpdateDelegated=DelegatedControlUpdate; |
15 | target.Invoke(d, new object []{c,callback,args}); |
16 | } |
17 | else |
18 | { |
19 | callback(args); |
20 | } |
21 | } |
01 | private void button1_Click( object sender,EventArgse) |
02 | { |
03 | Threadthread= new Thread(()=> |
04 | { |
05 | for ( int i=0;i<100000;i++) |
06 | { |
07 | DelegatedControlUpdate(label1,args=> |
08 | { |
09 | label1.Text=( string )args[0]; |
10 | label1.Refresh(); |
11 | },i.ToString()); |
12 | } |
13 | }); |
14 | thread.Start(); |
15 | } |
相关文章推荐
- 在非UI线程中改变UI控件属性的通用方法
- 转 在非 UI线程中改变UI控件属性的通用方法
- C#用副线程改主线程(UI线程)的控件属性的方法(包括Winform和WPF)
- C# Winform使用线程改变窗体控件的属性
- 常量,字段,构造方法 调试 ms 源代码 一个C#二维码图片识别的Demo 近期ASP.NET问题汇总及对应的解决办法 c# chart控件柱状图,改变柱子宽度 使用C#创建Windows服务 C#服务端判断客户端socket是否已断开的方法 线程 线程池 Task .NET 单元测试的利剑——模拟框架Moq
- 使用JavaScript脚本无法直接改变Asp.net中Checkbox控件的Enable属性的解决方法
- winform的treeview控件点击鼠标右键就改变SelectedNode属性的方法
- C# Winform 跨线程更新UI控件常用方法汇总
- 线程里改变控件的属性,禁止提示错误
- Android开发-UI控件:选项卡切换时改变布局中内容的方法
- C# Winform 跨线程更新UI控件常用方法总结(转)
- Android平台在UI Thread中执行非UI线程中定义的代码片段的几种方法
- C# Winform 跨线程更新UI控件常用方法汇总
- C# Winform 跨线程更新UI控件常用方法总结(转)
- UI之各种控件的属性及使用方法说明(三)
- 子线程改变UI线程的方法
- C# 跨线程访问或者设置UI线程控件的方法
- C#中跨线程操作控件 --- InvokeRequired 属性 与Invoke方法
- UI之各种控件的属性及使用方法说明(一)
- 使用JavaScript脚本无法直接改变Asp.net中Checkbox控件的Enable属性的解决方法