C# 在某个线程上创建的控件不能成为在另一个线程上创建的控件的父级

来源:百度知道 编辑:UC知道 时间:2024/06/15 22:17:52
这是一个类。这个类启动了一个线程。用这个线程在form1里添加一个textbox.
class Class1
{
Form1 f1;
TextBox textBox1;
public Class1(Form1 f1)
{
this.f1 = f1;
textBox1 = new TextBox();
textBox1.Location = new System.Drawing.Point(94, 189);
textBox1.Name = "textBox1";
textBox1.Size = new System.Drawing.Size(100, 21);
textBox1.TabIndex = 0;
Thread t = new Thread(new ThreadStart(add));
t.Start();
}
public void add()
{
f1.Controls.Add(textBox1);
}
}

---------------------------------------------------------------

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}

哈哈,这个问题我也碰到过的!
MSDN上的解释说.NETFramework2.0前的时代可以通过子线程在父线程创建控件,当时你上述的代码是正确的。
但是使用线程操作常常会是复杂而且危险的,所以微软在.NETFramework2.0及以后版本都对线程的操作进行了限制。
像你的代码流程应该是这样的:
首先在form1的窗体载入中新建了一个Class1对象并将本身的引用传递进入其构造函数,然后在Class1的构造函数中创建一个线程。该线程所代理的方法事件是本类中的一个add方法。而add方法的内容则是在form1上放一个textbox.
然而这个流程你需要注意的有几个问题:
1.哪个是主线程?所谓主线程是第一个启动的线程,是从main开始的。form1的这个窗体是由主线程创建的。
2.Thread t的线程是什么?t是由主线程创建的,t的操作内容是在由主线程创建的窗体上放一个textbox.
也就是说,t的操作是跨线程的窗体操作。虽然楼主把CheckForIllegalCrossThreadCalls 设置成了false,但是还存在在某个线程上创建的控件不能成为在另一个线程上创建的控件的父级这个异常。
这个问题说实话我也不懂,不好说什么。可能微软禁止了一个线程在另一个线程上添加自己的控件,因为这种做法着实不安全。
至于解决办法:
1.不要线程,只在一个主线程中操作。此时你在class1中添加控件也好,在form1中写个方法来添加控件也好,都是可行的。
2.通过代理来实现。在对form1对象的操作中
if(form1.InvokeRequired)
{
form1.Invoke(d);//d为在主线程中创建的代理引用
//d所代理的方法应该是添加控件的内容
}
else
{
form1.Controls.add(textBox1);//直接使用
}
//代码
class Class1
{
Form1 f1;
TextBox textBox1;