首页新闻找找看学习计划

C#在什么情况下控件属性赋值会无效

0
悬赏园豆:200 [已解决问题] 解决于 2016-10-20 14:12

我所知道的

1、直接给子控件属性赋值,父控件不动的情况

2、非主线程的控件赋值,在不做任何跨线程的操作情况下

 

 

 

最近遇到的一个问题是有关控件属性不能赋值的,希望大家能帮忙

有加过   CheckForIllegalCrossThreadCalls = false;这个

也用过别人封装好的invoke类,都是只能在winform界面操作控件属性,别的类都赋值不成功

一首歌听到忘世的主页 一首歌听到忘世 | 初学一级 | 园豆:138
提问于:2016-10-09 13:58
< >
分享
最佳答案
0

代码demo发给我,我给你解决

收获园豆:100
田麦成 | 小虾三级 |园豆:1982 | 2016-10-09 14:42

怎么发给你,要不要什么联系方式,我qq 819606850

一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-09 14:43
其他回答(3)
0

除了你说的第二点,跨线程操作需要用invoke,其它情况都可以。

至于是否有效,要看你怎么理解 ,是赋值的时候 报错?只要不报错,那就是赋上了。

至于是否产生效果上的影响,那么要看你的这个值会不会被用的,有的属性只有在特定的情况下,才会被特定的事件调用一下,所以,之后你再赋值是可能就没有你说的那种“有效”了。还有一种情况就是,你给的太早了,可能被它后来触发的事件中的代码给覆盖了,这种情况也是有的。

ensleep | 园豆:1391 (小虾三级) | 2016-10-09 14:13

我做过一个简单的demo,可以用另一个类来控制控件的visible,显示和不显示,

但是在实际项目中,从另一个类赋值给控件visible为true的时候,没有赋值上去,(原本为false)

还有一个我不理解的地方就是,在这个时候,this.visible也为false了,我想这是导致赋值不上去的原因,不过我解决不了,能帮我分析一下么,我可以给你代码

支持(0) 反对(0) 一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-09 14:17

赋值的时候没有报错,但是我断点调试的时候,原属性是false,我赋值true给他,但是跳下一句语句的时候,依旧是false,代码,在二楼,你看看是不是能理解,,

支持(0) 反对(0) 一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-09 14:33
0

举个例子呗?ps:有些效果,不单单是一个属性起作用的

收获园豆:30
jello chen | 园豆:7091 (大侠五级) | 2016-10-09 14:16

 


简单介绍一下我自己练手的即时通讯,有一个类是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;
        }
支持(0) 反对(0) 一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-09 14:24

一旦这个文件传输的要求出现,等跳到执行赋值属性操作的时候,原本窗口的this.visible的值就变成false了,这是为什么

支持(0) 反对(0) 一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-09 14:29

@一首歌听到忘世: 你这个不报错么?

 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         }

应该这样写

支持(0) 反对(0) ensleep | 园豆:1391 (小虾三级) | 2016-10-09 14:53

@ensleep:赋值还是失败的 ,我原本不报错的原因应该是加了CheckForIllegalCrossThreadCalls这个语句,现在我去掉了

支持(0) 反对(0) 一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-09 15:20

@ensleep: 代码运行直接到了else里面,没有走上面一步,和我原本写的没什么差别了

支持(0) 反对(0) 一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-09 15:26

@一首歌听到忘世: 去掉CheckForIllegalCrossThreadCalls,就可以进我那里面了,之所有在.NET3以后加入了CheckForIllegalCrossThreadCalls这个特性,就是为了防止 你这种问题,一边界面正在绘制,一边你要给赋值。而且,即使改成那样,你断点的时候 也是看不到效果的,因为INVOKE是放在了事件中,你直接跑看效果就可以了。

你的那个this是主窗体吧?

支持(0) 反对(0) ensleep | 园豆:1391 (小虾三级) | 2016-10-09 15:46

@ensleep: this是主窗体,跑下来结果还是控件没有显示,如果把else那一部分去掉就会抛异常,在创建窗口句柄之前,布恩那个在控件上调用invoke或者beginInvoke

支持(0) 反对(0) 一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-09 15:57

@一首歌听到忘世: ^V^,你的这个操作太早了吧,是不是当时控件还没有初始化啊————,代码发过来吧。ensleep@ensleep.net

支持(0) 反对(0) ensleep | 园豆:1391 (小虾三级) | 2016-10-09 16:16

@ensleep: 代码发过来了,你看看,我太懵逼了。

支持(0) 反对(0) 一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-09 16:58

@ensleep: 要不你加我qq 819606850

支持(0) 反对(0) 一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-09 16:59

@一首歌听到忘世: 你的那个thread类有两个构造方法,第二个构造方法你用到了么?

你只有


public void SendValue()
{
ClassUdpThread udpThread = new ClassUdpThread(this);
}

这个地方用到了它,但是,你这个SendValue没在任何地方被调用啊

支持(0) 反对(0) ensleep | 园豆:1391 (小虾三级) | 2016-10-09 17:35

@ensleep: 这是我之前尝试的解决方法,不过没有成功,我忘了注释了,第二个构造方法也是因为因为用这个解决方法才写的,不过没效果,就放在那了。

网上说的将整个winform当作参数传给thread类,来做控件的更改,不过,没有什么效果。后来就丢那了

支持(0) 反对(0) 一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-09 17:42

@一首歌听到忘世: 我刚到家,帮你看一下代码吧

支持(0) 反对(0) ensleep | 园豆:1391 (小虾三级) | 2016-10-09 19:19

@一首歌听到忘世: 邮件回了一个给你,你的代码太乱了,好多地方有的没的。我给你写了个新的类,那个类应该就是你想要的,它会不停地变动你的那几个控件的显示隐藏状态,每秒换一次,界面上可以看到效果,你照着抄吧。

支持(0) 反对(0) ensleep | 园豆:1391 (小虾三级) | 2016-10-09 19:31

@ensleep: 你的代码是可行,但是不能解决我的问题,后来解决了,解决的办法是将主线程每次更改控件属性后都将参数传给thread那个类,然后就能赋值了。,多谢多谢

支持(0) 反对(0) 一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-10 11:35

@一首歌听到忘世: 每次都传过去不合适吧,你应该在构造函数里面直接把main对象传过去。

支持(0) 反对(0) ensleep | 园豆:1391 (小虾三级) | 2016-10-10 12:58

@ensleep: 讲讲,具体一点,我只能说是解决了这个问题,但是应该解决的不够漂亮,

支持(0) 反对(0) 一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-10 13:06

@一首歌听到忘世: 把你的那个类废掉,用我的那个类,缺的东西往我那个里面补,我的那个类的构造方法别动。就可以了

支持(0) 反对(0) ensleep | 园豆:1391 (小虾三级) | 2016-10-10 20:21
0

通过 invoke 是可以的

收获园豆:70
seayxu | 园豆:5468 (大侠五级) | 2016-10-09 15:55

ni可以看看我的代码,虽然应该是可以的,但是,控件还是没有显示出来,我的代码可能有点问题,但是不知道出问题的原因 qq 819606850

支持(0) 反对(0) 一首歌听到忘世 | 园豆:138 (初学一级) | 2016-10-09 15:59
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册