现实现窗体内通过panel显示新窗体,由于显示窗体较多(6个),每个窗体有的访问数据库,有的显示FLash,有的访问硬件,因此想通过多线程解决,显示多线程实现了,但是无法简易访问个窗体属性,方法,控件?寻求解决方法?
private Thread thread01; ////定义一个委托,用于打开窗体
public delegate void ShowCallback(); //线程方法
private void OpenForm01()
{
if (this.InvokeRequired)
{
ShowCallback d = new ShowCallback(OpenForm01);
this.Invoke(d, new object[] { });
}
else
{
FrmAddCarNo frmAddCarNo = new FrmAddCarNo();
frmAddCarNo.TopLevel = false;
frmAddCarNo.Visible = true;
//添加
this.panelCarNo.Controls.Add(frmAddCarNo as Control);
}
} //启动线程
private void StartThread01()
{
thread01 = new Thread(new ThreadStart(OpenForm01));
//thread01.IsBackground = true;
thread01.Start();
}
private Thread thread01; ////定义一个委托,用于打开窗体
public delegate void ShowCallback(); //线程方法
private void OpenForm01()
{
if (this.InvokeRequired)
{
ShowCallback d = new ShowCallback(OpenForm01);
this.Invoke(d, new object[] { });
}
else
{
FrmAddCarNo frmAddCarNo = new FrmAddCarNo();
frmAddCarNo.TopLevel = false;
frmAddCarNo.Visible = true;
//添加
this.panelCarNo.Controls.Add(frmAddCarNo as Control);
}
} //启动线程
private void StartThread01()
{
thread01 = new Thread(new ThreadStart(OpenForm01));
//thread01.IsBackground = true;
thread01.Start();
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private delegate void MoveLabel(int val);//声明代理
bool bWay = true;
Thread td;
private void Form1_Load(object sender, EventArgs e)
{
td = new Thread(new ThreadStart(ThreadFun));
td.Start();
this.button1.Text = "停止";
} private void button1_Click(object sender, EventArgs e)
{
if(td.ThreadState == ThreadState.Suspended)
{
td.Resume();
this.button1.Text = "停止";
}
else
{
this.button1.Text = "开始";
td.Suspend();
}
}
void SetOffset(int val)
{
this.label1.Location = new System.Drawing.Point(label1.Location.X + val, label1.Location.Y);
}
private void ThreadFun()
{
while (true)
{
int xF = this.Size.Width;
int xL = this.label1.Location.X;
int lblWidth = this.label1.Size.Width;
if (bWay)
{
if (xL + lblWidth < xF)
{
if (this.InvokeRequired)
{
MoveLabel d = new MoveLabel(SetOffset);
object[] arg = new object[] { 1 };//要传入的参数值
this.Invoke(d, arg);
}
}
else
{
bWay = false;
}
}
else
{
if (xL >= 0)
{
if (this.InvokeRequired)
{
MoveLabel d = new MoveLabel(SetOffset);
object[] arg = new object[] { -1 };//要传入的参数值
this.Invoke(d, arg);
}
}
else
{
bWay = true;
}
}
Thread.Sleep(5);
}
} private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
td.Abort();
}
}
}
demo 下载:http://download.csdn.net/source/1584578
例如:我把FrmAddCarNo frmAddCarNo定义在主窗体,frmAddCarNo = new FrmAddCarNo();实例化在线程内,那么frmAddCarNo到底属于主线程还是新建线程呢?
frmAddCarNo = new FrmAddCarNo();// 分配内存
=============================================
frmAddCarNo到底属于主线程还是新建线程呢?严格来讲不能这么问,如果非要这么问是属于主线程的,C#是线程安全的,所以要在线程之外访问控件也必须保证线程安全,但是在线程之外访问控件是被看做非线程安全的,所以这里用代理访问。例子已经给你了,先看下吧。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;namespace WindowsApplication257
{
public partial class Form1 : Form
{
Panel panelCarNo = new Panel();
bool Created = false; public Form1()
{
InitializeComponent(); panelCarNo.Parent = this;
panelCarNo.Dock = DockStyle.Fill; this.Shown += new EventHandler(Form1_Shown);
} void Form1_Shown(object sender, EventArgs e)
{
new Thread(new ThreadStart(OpenFormThread)).Start(); while (!Created)
Application.DoEvents(); Form F = (Form)this.panelCarNo.Controls.Find("XXX", true)[0];
F.Text = "ZZZZZZZZ";
} delegate void ShowCallback(); void OpenFormThread()
{
this.Invoke(new ShowCallback(Do));
Created = true;
} void Do()
{
Form frmAddCarNo = new Form();
frmAddCarNo.TopLevel = false;
frmAddCarNo.Visible = true;
frmAddCarNo.Parent = this.panelCarNo;
frmAddCarNo.Name = "XXX";
}
}
}
{
FrmAddCarNo frmaddCarNo = (FrmAddCarNo)this.panelCarNo.Controls[0]; this.lbl_View02.Text = frmaddCarNo.GetCarNo();
}这样写有什么隐患?
private void btn_Print_Click(object sender, EventArgs e)
{
try
{
frmaddCarNo = (FrmAddCarNo)this.panelCarNo.Controls[0]; this.lbl_View02.Text = frmaddCarNo.GetCarNo();
}
catch
{
throw;
}
finally
{
frmaddCarNo = null;
GC.Collect();
} }
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
再不行就用
this.Invoke(new ThreadStart(up));