虚心求教c#在其他类中跨线程调用form中的控件,如何实现呢?

虚心求教,如图所示,我想在tcpsvr.cs类里面,实现对orderform中的textbox1追加文本,于是我就在tcpsvr中建了一个可传递textbox属性的构造函... 虚心求教,如图所示,我想在tcpsvr.cs类里面,实现对order form中的textbox1追加文本,于是我就在tcpsvr中建了一个可传递textbox属性的构造函数,但是,当程序运行时到 textbox.appendtext()时,提示我跨线程调用,请问如何解决呢? 展开
 我来答
CodeBlove
2014-09-10 · TA获得超过3364个赞
知道小有建树答主
回答量:936
采纳率:79%
帮助的人:244万
展开全部

不建议在类中直接访问控件,这不符合低耦合的设计要求,有些正式项目维护很麻烦的,特别是跨线程。

下面用我自己的一个扫描枪项目举例

 

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);//添加事件响应
追问
谢谢,我要学的还很多啊
shuibiyy
2014-09-10 · TA获得超过1724个赞
知道小有建树答主
回答量:446
采纳率:100%
帮助的人:143万
展开全部
方法(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)
追问
谢谢,我还要多多学习
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
linsloony
2014-09-10 · TA获得超过362个赞
知道小有建树答主
回答量:212
采纳率:0%
帮助的人:283万
展开全部
//请参考:
if (textbox.InvokeRequired)
{
    textbox.Invoke(new MethodInvoker(() => { textbox.AppendText("xx"); }));
}
else
{
    textbox.AppendText("xx");
}

欢迎追问。

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式