缘起
今天一群里有人问到这个功能,其实应该挺简单,但提问题的人问题的出发点并没有描述清楚。因此,一个简简单单的需求,就引起了群内热烈的讨论。他想实现的功能就是有一堆的checkbox复选框,同时提供一个复选框作为“全选”、“全不选”的功能。下面看看这个功能如何去实现,先上效果:
Show me the Code
1 | public Form6() |
接下来要说的是,关于全选CheckBox事件的选取。最初,该同学提的问题是:有没有遇到过按钮点击没反应?但随着群里大家一人一嘴的提示,该同学渐渐把自己的需求给提出来了,他的代码是用“全选”CheckBox的CheckChanged事件中去修改“子选项”里面的6个CheckBox选中状态。然而,他又想到:如果不是点“全选”CheckBox,而是下面6个CheckBox挨个点,上面那个全选的状态怎么改。于是该同学又给下面六个CheckBox分别注册了CheckChanged事件,去判断并修改全选CheckBox的状态。最终,导致了他所谓的事件嵌套,跳不出来了。
复盘
其实放弃使用全选的CheckChanged事件,选用Click事件就可以解决掉全选的两个Check属性更改的来源:1是来自自己的点击更改状态,2.是来自子选项中所有checkbox都选中,间接导致的全选。
为什么全选反选的Checkbox1使用CheckChanged事件不行呢?我们假设Checkbox1注册的是CheckChanged事件,处理代码和Click事件中的代码相同。看下面的动作:
当子复选框全部被选中后,Checkbox1复选框处于Checked属性为True、Text属性为反选。此时,点击任意一个子复选框,直接进入if判断中的else分支。而else分支并未判断所有子复选框的状态,而是直接给checkbox1属性进行修改。因此出现上面的状况。接下来,给子复选框Changed事件进行一下修改,这样全选反选的Checkbox1无论使用Click事件还是CheckChanged事件,都可以实现功能。
1 | private void Ck_CheckedChanged(object sender, EventArgs e) |
后记
这是一篇很早之前发布在博客园的文章了,最近整理博客,准备搬过来。但觉得原来写的有些单薄,于是复盘了一下。结果发现,原来还是考虑的不是很多,只是简单的实现了群里同学的需求。仔细分析下来,还是某个函数的代码考虑的不够全面。
同时,复盘过程中还发现了checkbox实际上有checkchanged事件和checkstatechanged事件,这两个都是通过checkbox的选中状态变化来触发事件。但判断依据不同,checked属性通过布尔值来判断,checkstate通过一个枚举值判断(默认是两个,如果让checkbox有三种状态,需要将checkbox的ThreeState属性设置为True)。
ThreeState分别是:
- Checked(打勾)
- UnChecked(空心)
- Indeterminate(黑色实心)
- 本文作者: 达文西
- 本文链接: https://edsiongithub.github.io/2021/05/17/0009/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!