虚心求教c#在其他类中跨线程调用form中的控件,如何实现呢?
虚心求教,如图所示,我想在tcpsvr.cs类里面,实现对orderform中的textbox1追加文本,于是我就在tcpsvr中建了一个可传递textbox属性的构造函...
虚心求教,如图所示,我想在tcpsvr.cs类里面,实现对order form中的textbox1追加文本,于是我就在tcpsvr中建了一个可传递textbox属性的构造函数,但是,当程序运行时到 textbox.appendtext()时,提示我跨线程调用,请问如何解决呢?
展开
3个回答
展开全部
不建议在类中直接访问控件,这不符合低耦合的设计要求,有些正式项目维护很麻烦的,特别是跨线程。
下面用我自己的一个扫描枪项目举例
1、在你的业务类中定义事件委托,将要处理的参数通过事件传递给事件函数(如果你传递的数据较多,需要另外定义一个特定参数类,使用属性定义包含你要传递的数据)。
public delegate void StartScanning(object Sender,string text);//定义扫描事件的委托
public event StartScanning OnStartScanning; //定义扫描事件对象,该对象用于外部程序挂接事件响应函数
//定义一个发送事件的函数
private void SendStartScanningEvent(string text)
{
if (OnStartScanning != null)
OnStartScanning(_Sender, text);//_Sender是调用该对象时传入的发生源,即某文本框控件,此处传回给事件处理(响应)函数 ,其中text为扫描到的并经过业务对象检查后的文本(条码)
}
2、在你的业务类中需要操作控件地方,通过事件发送函数触发事件,将参数发送给事件函数处理。
下面在窗口代码中定义
3、为事件响应函数定义一个异步委托,该委托由事件响应函数调用,实现跨线程访问窗口控件
private delegate void OnThreadStart(object sender);
4、实例化业务对象,定义一个为该对象服务的,处理窗口控件的事件响应函数。
ScanningGunMonitor ProductScanMonitor = new ScanningGunMonitor();
private void ProductScanMonitor_OnStartScanning(object sender, string Text)
{
//这里是重点 ,自定义类对象的事件触发会导致与窗口不在一个线程,通过下面的代码进行异步访问重新访问自己
if (InvokeRequired)
{
OnThreadStart mydelgate = new OnThreadStart(ProductScanMonitor_OnStartScanning);
//异步的委托
this.Invoke(mydelgate, new object[] { sender, Text });
return;
}
//窗口线程可执行的代码
TextBox box = (TextBox)sender;
box.Text = Text;
box.Select(box.TextLength, 0);
}
5、在初始化的地方为该对象添加定义的事件响应函数,业务对象触发事件时会调用它。
ProductScanMonitor.OnStartScanning += new ScanningGunMonitor.StartScanning(ProductScanMonitor_OnStartScanning);//添加事件响应
追问
谢谢,我要学的还很多啊
展开全部
方法(1) 设置 form的CheckForIllegalCrossThreadCalls=false;
方法(2)使用委托:
tcpsvr.cs类外声明委托
public delegate void AppendMsgEventHandler(string msg);
public class tcpsvr
{
public AppendMsgEventHandler AppendMsg; tcpsvr里面
使用追加时
AppendMsg(receiveData);
}
在order 类声明方法
private void appendMsg(string msg)
{
textbox.appendtext(msg)
}
创建 order对像 时
tcpsvr svr=new tcpsvr();
svr.AppendMsg=new AppendMsgEventHandler(appendMsg);
方法(3)依然使用委托
在order 声明委托 及委托变量
public delegate void AppendMsgEventHandler(string msg);
public AppendMsgEventHandler AppendMsg=new AppendMsgEventHandler(appendMsg);
private void appendMsg(string msg)
{
textbox.appendtext(msg)
}
将order 对象传给tcpsvr
在tcpsvr 类里调用时
order(对象).invoke(order(对象).AppendMsg,receiveData)
方法(2)使用委托:
tcpsvr.cs类外声明委托
public delegate void AppendMsgEventHandler(string msg);
public class tcpsvr
{
public AppendMsgEventHandler AppendMsg; tcpsvr里面
使用追加时
AppendMsg(receiveData);
}
在order 类声明方法
private void appendMsg(string msg)
{
textbox.appendtext(msg)
}
创建 order对像 时
tcpsvr svr=new tcpsvr();
svr.AppendMsg=new AppendMsgEventHandler(appendMsg);
方法(3)依然使用委托
在order 声明委托 及委托变量
public delegate void AppendMsgEventHandler(string msg);
public AppendMsgEventHandler AppendMsg=new AppendMsgEventHandler(appendMsg);
private void appendMsg(string msg)
{
textbox.appendtext(msg)
}
将order 对象传给tcpsvr
在tcpsvr 类里调用时
order(对象).invoke(order(对象).AppendMsg,receiveData)
追问
谢谢,我还要多多学习
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
//请参考:
if (textbox.InvokeRequired)
{
textbox.Invoke(new MethodInvoker(() => { textbox.AppendText("xx"); }));
}
else
{
textbox.AppendText("xx");
}
欢迎追问。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询