问题描述
首先说一下,对于vb.net我是新手。在阅读别人代码时,遇到checkbox的bug,就想动手解决。其基本的逻辑是这样的:在win.form的一个应用中,有3个checkbox,首先运行一个主程序,其中把第一个checkbox1的状态修改为true,如下:sub......checkbox1.Checked=true......Endsub
运行完后,呈现一个窗体。然后,如果用户点击其中一个checkbox,如果这个checkbox是unchecked,让这个checkbox状态改为checked,其中两个checkbox状态改为unchecked;如果状态是checked,则该checkbox的状态修改为unchecked,其中两个也改为unchecked。大致代码如下:Subcheckbox1_CheckedChanged(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)Handlescheckbox1.CheckedChangedIfcheckbox1.CheckState=CheckState.UncheckedThencheckbox1.CheckState=CheckState.Checkedcheckbox2.CheckState=CheckState.Uncheckedcheckbox3.CheckState=CheckState.UncheckedElsecheckbox1.CheckState=CheckState.Uncheckedcheckbox1.CheckState=CheckState.Uncheckedcheckbox1.CheckState=CheckState.UncheckedEndIfEndSub
本来以为这个bug很简单,谁知道运行后我发现,当主程序中对checkbox1初次赋值后,需要修改其他两个checkbox的状态,又触发了进一步修改状态,谁知道上述代码形成了死循环。想了好久,觉得这个是简单问题,但怎么也找不到较好的解决方式。不知道哪位高智商大神能帮助小弟一把?在此感激涕零了!在线等!
解决方案
解决方案二:
1.判断当前点击的状态2.如果是True,则改为False3.如果是False,则其他的全部为False,然后再把这个改为true
解决方案三:
本来以为这个bug很简单,谁知道运行后我发现,当主程序中对checkbox1初次赋值后,需要修改其他两个checkbox的状态,又触发了进一步修改状态,谁知道上述代码形成了死循环这还想不到问题的解决办法?在修改之前移除所有checkbox注册的CheckedChanged事件,在修改完之后再统一注册事件而且你三个方法都是统一的逻辑,完全可以只注册到一个方法上,然后通过事件方法的sender参数来确定当前触发事件的是哪个checkbox
解决方案四:
自己定义一个标识就好。DimeditingAsBoolean=FalseSubcheckbox1_CheckedChanged(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)Handlescheckbox1.CheckedChangedIfediting=FalseThenediting=TrueIfcheckbox1.CheckState=CheckState.UncheckedThencheckbox1.CheckState=CheckState.Checkedcheckbox2.CheckState=CheckState.Uncheckedcheckbox3.CheckState=CheckState.UncheckedElsecheckbox1.CheckState=CheckState.Uncheckedcheckbox1.CheckState=CheckState.Uncheckedcheckbox1.CheckState=CheckState.UncheckedEndIfediting=FalseEndIfEndSub
解决方案五:
不用checkbox1的checkedchange事件,用它的clicked事件嘛,click事件里的逻辑一样。主程序改了checkbox1的checked属性也不影响
解决方案六:
劳驾版主莅临。小弟是刚学vb.net,对于下面讲的修改之前移除所有checkbox注册的CheckedChanged事件,在修改完之后再统一注册事件。这个版主能否用代码简单说明一下?这里先谢过了。引用2楼starfd的回复:
本来以为这个bug很简单,谁知道运行后我发现,当主程序中对checkbox1初次赋值后,需要修改其他两个checkbox的状态,又触发了进一步修改状态,谁知道上述代码形成了死循环这还想不到问题的解决办法?在修改之前移除所有checkbox注册的CheckedChanged事件,在修改完之后再统一注册事件而且你三个方法都是统一的逻辑,完全可以只注册到一个方法上,然后通过事件方法的sender参数来确定当前触发事件的是哪个checkbox
解决方案七:
引用楼主u011552243的回复:
本来以为这个bug很简单,谁知道运行后我发现,当主程序中对checkbox1初次赋值后,需要修改其他两个checkbox的状态,又触发了进一步修改状态,谁知道上述代码形成了死循环。想了好久,觉得这个是简单问题,但怎么也找不到较好的解决方式。不
这是一个比较基本的“编程模式”问题(模式,就是一些应该变成“习惯”的小伎俩,这些不经意的习惯又体现着程序员的训练)。要改变一个控件的属性,应该首先判断一下“到底有没有必要修改”。例如应该写if(!checkbox1.Checked)checkbox1.Checked=true;
对于其它的也是如此,控件的任何属性修改都应该如此。这是因为——控件的属性通常会触发事件。如果先判断后修改,那么就不会产生事件触发循环。如果果真触发了死循环,那么你的业务逻辑本身就是死循环,而不是编程问题。
解决方案八:
CheckBox[]boxArr=newCheckBox[3];privatevoidForm1_Load(objectsender,EventArgse){boxArr[0]=this.checkBox1;boxArr[1]=this.checkBox2;boxArr[2]=this.checkBox3;this.BindEvent();}privatevoidBindEvent(boolbind=true){for(vari=0;i<boxArr.Length;i++){if(bind){boxArr[i].CheckedChanged+=CheckBox_CheckedChanged;}else{boxArr[i].CheckedChanged-=CheckBox_CheckedChanged;}}}privatevoidCheckBox_CheckedChanged(objectsender,EventArgse){varnowCheckBox=senderasCheckBox;if(nowCheckBox!=null){this.BindEvent(false);for(vari=0;i<boxArr.Length;i++){if(boxArr[i]!=nowCheckBox){boxArr[i].CheckState=CheckState.Unchecked;}}this.BindEvent();}}
我写了C#版的,对于当前被点击的CheckBox其实没必要做任何操作
解决方案九:
如果同一时刻只能选择其中一个,你可以用另外一个控件radiobutton,添加控件的时候把默认选的那个控件属性checked设置为true就行了。
解决方案十:
其实你用checkbox不要在主程序启动的时候设置,而在添加控件的时候设置,这样就不会有这个问题了。
解决方案十一:
程序启动的时候是不是不应该处理,是,那么在程序启动后加标记,也就是说在formload最后标记一下,再在checkboxchanged事件中,把所有都加上这个标记,那么程序在初始化的时候就不会运行changed里的东西了