我所知道的
1、直接给子控件属性赋值,父控件不动的情况
2、非主线程的控件赋值,在不做任何跨线程的操作情况下
最近遇到的一个问题是有关控件属性不能赋值的,希望大家能帮忙
有加过 CheckForIllegalCrossThreadCalls = false;这个
也用过别人封装好的invoke类,都是只能在winform界面操作控件属性,别的类都赋值不成功
代码demo发给我,我给你解决
怎么发给你,要不要什么联系方式,我qq 819606850
除了你说的第二点,跨线程操作需要用invoke,其它情况都可以。
至于是否有效,要看你怎么理解 ,是赋值的时候 报错?只要不报错,那就是赋上了。
至于是否产生效果上的影响,那么要看你的这个值会不会被用的,有的属性只有在特定的情况下,才会被特定的事件调用一下,所以,之后你再赋值是可能就没有你说的那种“有效”了。还有一种情况就是,你给的太早了,可能被它后来触发的事件中的代码给覆盖了,这种情况也是有的。
我做过一个简单的demo,可以用另一个类来控制控件的visible,显示和不显示,
但是在实际项目中,从另一个类赋值给控件visible为true的时候,没有赋值上去,(原本为false)
还有一个我不理解的地方就是,在这个时候,this.visible也为false了,我想这是导致赋值不上去的原因,不过我解决不了,能帮我分析一下么,我可以给你代码
赋值的时候没有报错,但是我断点调试的时候,原属性是false,我赋值true给他,但是跳下一句语句的时候,依旧是false,代码,在二楼,你看看是不是能理解,,
举个例子呗?ps:有些效果,不单单是一个属性起作用的
简单介绍一下我自己练手的即时通讯,有一个类是ClassUdpThread,专门用来接收消息标识符的,比如有人上线,下线,发文件之类的,这时候里面会作出反应,在主界面也就是winform界面里面,在等到别人发文件给你的时候,这个类收到消息,做出的反应是将 winform上面接收和拒绝按钮给显示出来,但是这时候赋值不上去,
ClassUdpThread 。。。 case ":DATA:": { string[] mBody = MsgBody.Split('|'); string msgName = mBody[0]; string msgIP = mBody[1]; string msgFileName = mBody[2]; string msgFileLen = mBody[3]; GetLocalIp(); if(msgIP ==localIP) { mainForm.ShowFileControls(); } break; } 。。。 mainForm的代码里面 public void ShowFileControls() { labelMessage.Visible = true; linkLabelAccept.Visible = true; linkLabelAccept.Enabled = true; linkLabelRefuse.Visible = true; linkLabelRefuse.Enabled = true; }
一旦这个文件传输的要求出现,等跳到执行赋值属性操作的时候,原本窗口的this.visible的值就变成false了,这是为什么
@一首歌听到忘世: 你这个不报错么?
1 public void ShowFileControls() 2 { 3 if (this.InvokeRequired) 4 { 5 this.Invoke(new Action(() => 6 { 7 labelMessage.Visible = true; 8 linkLabelAccept.Visible = true; 9 linkLabelAccept.Enabled = true; 10 linkLabelRefuse.Visible = true; 11 linkLabelRefuse.Enabled = true; 12 })); 13 }else 14 { 15 labelMessage.Visible = true; 16 linkLabelAccept.Visible = true; 17 linkLabelAccept.Enabled = true; 18 linkLabelRefuse.Visible = true; 19 linkLabelRefuse.Enabled = true; 20 } 21 }
应该这样写
@ensleep:赋值还是失败的 ,我原本不报错的原因应该是加了CheckForIllegalCrossThreadCalls这个语句,现在我去掉了
@ensleep: 代码运行直接到了else里面,没有走上面一步,和我原本写的没什么差别了
@一首歌听到忘世: 去掉CheckForIllegalCrossThreadCalls,就可以进我那里面了,之所有在.NET3以后加入了CheckForIllegalCrossThreadCalls这个特性,就是为了防止 你这种问题,一边界面正在绘制,一边你要给赋值。而且,即使改成那样,你断点的时候 也是看不到效果的,因为INVOKE是放在了事件中,你直接跑看效果就可以了。
你的那个this是主窗体吧?
@ensleep: this是主窗体,跑下来结果还是控件没有显示,如果把else那一部分去掉就会抛异常,在创建窗口句柄之前,布恩那个在控件上调用invoke或者beginInvoke
@一首歌听到忘世: ^V^,你的这个操作太早了吧,是不是当时控件还没有初始化啊————,代码发过来吧。ensleep@ensleep.net
@ensleep: 代码发过来了,你看看,我太懵逼了。
@ensleep: 要不你加我qq 819606850
@一首歌听到忘世: 你的那个thread类有两个构造方法,第二个构造方法你用到了么?
你只有
public void SendValue()
{
ClassUdpThread udpThread = new ClassUdpThread(this);
}
这个地方用到了它,但是,你这个SendValue没在任何地方被调用啊
@ensleep: 这是我之前尝试的解决方法,不过没有成功,我忘了注释了,第二个构造方法也是因为因为用这个解决方法才写的,不过没效果,就放在那了。
网上说的将整个winform当作参数传给thread类,来做控件的更改,不过,没有什么效果。后来就丢那了
@一首歌听到忘世: 我刚到家,帮你看一下代码吧
@一首歌听到忘世: 邮件回了一个给你,你的代码太乱了,好多地方有的没的。我给你写了个新的类,那个类应该就是你想要的,它会不停地变动你的那几个控件的显示隐藏状态,每秒换一次,界面上可以看到效果,你照着抄吧。
@ensleep: 你的代码是可行,但是不能解决我的问题,后来解决了,解决的办法是将主线程每次更改控件属性后都将参数传给thread那个类,然后就能赋值了。,多谢多谢
@一首歌听到忘世: 每次都传过去不合适吧,你应该在构造函数里面直接把main对象传过去。
@ensleep: 讲讲,具体一点,我只能说是解决了这个问题,但是应该解决的不够漂亮,
@一首歌听到忘世: 把你的那个类废掉,用我的那个类,缺的东西往我那个里面补,我的那个类的构造方法别动。就可以了
通过 invoke 是可以的
ni可以看看我的代码,虽然应该是可以的,但是,控件还是没有显示出来,我的代码可能有点问题,但是不知道出问题的原因 qq 819606850