几年前在做一个项目的时候需要处理这样一种情况:
主窗体是隐藏的,程序中有一个线程在时时监控网络中传输的数据
一旦发现传输的数据出现新的类型就需要在主窗体的treeview控件中添加一个节点来记录这种类型数据。
由于当时比较菜鸟,就直接调用了窗体引用:mainfrm.dtviewer.Nodes.Add(dttype);
结果,编译正常,执行的时候却报了一个错误:不能操作不同线程中的控件(大概是这个意思,时间久了,忘记了)。
即便在这个窗体中的函数来调用这个操作也不能解决问题,还是报相同的错误。
相信有过开发经历的同志们一定都有过这样的经历:当你遇到一个从未出现过的问题时,往往通过中文msdn,或者在网上查找相关资料,可到最后却一无所获。最终还得上国外的技术网站来解决问题。
最后,我们终于在国外的一家网站上找到了类似的解决方法——使用delegate。
那就是在窗体类中实例化一个delegate,并且指向处理treeview的那个函数。当需要调用这个函数的时候直接运行dtviewer.Invoke(mydelegate,NULL);即可。
具体代码如下:
主窗体是隐藏的,程序中有一个线程在时时监控网络中传输的数据
一旦发现传输的数据出现新的类型就需要在主窗体的treeview控件中添加一个节点来记录这种类型数据。
由于当时比较菜鸟,就直接调用了窗体引用:mainfrm.dtviewer.Nodes.Add(dttype);
结果,编译正常,执行的时候却报了一个错误:不能操作不同线程中的控件(大概是这个意思,时间久了,忘记了)。
即便在这个窗体中的函数来调用这个操作也不能解决问题,还是报相同的错误。
相信有过开发经历的同志们一定都有过这样的经历:当你遇到一个从未出现过的问题时,往往通过中文msdn,或者在网上查找相关资料,可到最后却一无所获。最终还得上国外的技术网站来解决问题。
最后,我们终于在国外的一家网站上找到了类似的解决方法——使用delegate。
那就是在窗体类中实例化一个delegate,并且指向处理treeview的那个函数。当需要调用这个函数的时候直接运行dtviewer.Invoke(mydelegate,NULL);即可。
具体代码如下:
1 //有新的数据类型出现,获取配置信息
2 public void ShowNewType(ClassType NewType)
3 {
4 myMethodDelegate tmpdel = new myMethodDelegate(ShowTheType);
5 this.NowNewType = NewType
6 this.trvDDI.Invoke(tmpdel, null);
7 device = null;
8 tmpdel = null;
9 }
10
11 //仅被ShowTheType调用,用于在树形控件的线程上调用:
12 private void ShowTheType()
13 {
14 try {
15 ClassType tmpType= NowNewType;
16 devicenode = this.dtviewer.Nodes.Add(tmpType.FullName);
17 devicenode.Tag = tmpType
18 //将类型实例作为tag值
19 }
20 catch (Exception ex) {
21 Debug.WriteLine("ShowTheType:" + Err.Description);
22 }
23 }
2 public void ShowNewType(ClassType NewType)
3 {
4 myMethodDelegate tmpdel = new myMethodDelegate(ShowTheType);
5 this.NowNewType = NewType
6 this.trvDDI.Invoke(tmpdel, null);
7 device = null;
8 tmpdel = null;
9 }
10
11 //仅被ShowTheType调用,用于在树形控件的线程上调用:
12 private void ShowTheType()
13 {
14 try {
15 ClassType tmpType= NowNewType;
16 devicenode = this.dtviewer.Nodes.Add(tmpType.FullName);
17 devicenode.Tag = tmpType
18 //将类型实例作为tag值
19 }
20 catch (Exception ex) {
21 Debug.WriteLine("ShowTheType:" + Err.Description);
22 }
23 }