VS2005 注意事项(2)

在 .Net Framework 2.0 中如果跨线程调用控件会出现错误( InvalidOperationException 从不是创建控件 control name 的线程访问它。)如 test() 函数可能是跨线程的向 Form1listBox1 中加入项:
......
//假设 test() 运行于一不安全线程下

void  test()
{
    ......
    Form1 frm 
= new
 Form1();
    frm.listBox1.Items.Add(
"Test!"
);
    ......
}
......
解决它的一种方法是在窗体设计器生成的代码中加入
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
但这样就回到了 1.1 版本时代,显然不符合时代发展需要,所以另一种方法是要用安全的委托,利用出错时对象的 InvokeRequired 属性的值将为 true 的原理用 Invoke() 函数来处理。
[C#]
using  System;
using
 System.Collections.Generic;
using
 System.ComponentModel;
using
 System.Data;
using
 System.Drawing;
using
 System.Text;
using
 System.Windows.Forms;

namespace
 Test
{
    
public partial class
 Form1 : Form
    
{
        ......
        
//定义一个 CallBack 函数

        delegate void AddItemsCallBack(String s);

        
//CallBack 指向的函数

        public void AddItems(String s)
        
{   
        AddItemsCallBack cb 
= new
 AddItemsCallBack(AddItems);
        
if (this
.listBox1.InvokeRequired)
           
this.listBox1.Invoke(cb, new object[] { s }
);
        
else

           
this.listBox1.Items.Add(s);
        }

        ......
    }

}
[Visual Basic]
Public  Class Form1
    ......
    
'
定义一个 CallBack 函数
    
Delegate 
Sub AddItemsCallBack(ByVal s As String)

    
'
CallBack 指向的函数
    
Public 
Sub AddItems(ByVal s As String)
        
Dim cb As New AddItemsCallBack(AddressOf
 AddItems)
        
If Me.ListBox1.InvokeRequired Then

            
Me.ListBox1.Invoke(cb, New Object() {s})
        
Else

            
Me.ListBox1.Items.Add(s)
        
End If

    
End Sub

    ......
End Class
此外,当我们使用自定义方法操作控件时有时会发生空间代码被执行两次的现象,这个主要是由于事件被主动注册的缘故,使用 object. Events.Dispose() 来禁用事件列表。
[C#]
using  System;
using
 System.Collections.Generic;
using
 System.ComponentModel;
using
 System.Data;
using
 System.Drawing;
using
 System.Text;
using
 System.Windows.Forms;

namespace
 LabScriptTest
{
    
public partial class
 Form1 : Form
    
{
        
private void Form1_Load(object
 sender, EventArgs e)
        
{
            ........
            
//禁用事件列表

            this.Events.Dispose();
            
//设置

            ........
        }

    }

}
[Visual Basic]
Public  Class Form1

    
Private 
Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ........
        
'
禁用事件列表
        
Me
.Events.Dispose()
        
'
设置
        ........
    
End Sub


End Class
要注意的是,如果在设置之后再禁用事件列表将使窗体不能响应消息,另外,代码被重复执行的情况若发生在另一窗体中,在执行完程序并用 Form.Close() 关闭窗口后样式都不会改变,也就是说,下一次使用 Form.Show() 显示窗体时其加载时仍如前面关闭时一样。
若想在向窗体画图后立即更新窗体则需要使用 Invalidate() 函数,而不是 Update() 函数,前者会使全部区域无效而必须重新 Paint,后者只使未使用控件区域无效而重新 Paint。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值