C# 是否有一种更有效的方法根据选中的复选框进行操作?
我最近也遇到了这个问题,搜索这个问题还没有结果 比如说,我有四个复选框,我想根据它们中的哪一个在任何时候被选中来做一些事情C# 是否有一种更有效的方法根据选中的复选框进行操作?,c#,winforms,performance,checkbox,.net-4.0,C#,Winforms,Performance,Checkbox,.net 4.0,我最近也遇到了这个问题,搜索这个问题还没有结果 比如说,我有四个复选框,我想根据它们中的哪一个在任何时候被选中来做一些事情 if (CB1.Checked) { //Do things here if only checkbox 1 is checked. } else if (CB2.Checked) { //Do things here if only checkbox 2 is checked. } else if (CB3.Checked) { //Do thin
if (CB1.Checked)
{
//Do things here if only checkbox 1 is checked.
}
else if (CB2.Checked)
{
//Do things here if only checkbox 2 is checked.
}
else if (CB3.Checked)
{
//Do things here if only checkbox 3 is checked.
}
else //if (CB4.Checked)
{
//Do things here if only checkbox 4 is checked.
}
我相信大多数人都会倾向于使用上面的示例代码片段,或其变体。看起来很简单,对吧?但是如果。。。你不是只检查一个复选框吗
if (CB1.Checked && CB2.Checked)
{
//Do things here if only checkbox 1 & 2 is checked.
}
else if (CB2.Checked && CB3.Checked)
{
//Do things here if only checkbox 2 & 3 is checked.
}
else if (CB3.Checked && CB1.Checked)
{
//Do things here if only checkbox 3 & 1 is checked.
}
else if (CB4.Checked && CB1.Checked)
{
//Do things here if only checkbox 4 & 1 is checked.
}
else if (CB4.Checked && CB2.Checked)
{
//Do things here if only checkbox 4 & 2 is checked.
}
else //if (CB4.Checked && CB3.Checked)
{
//Do things here if only checkbox 4 & 3 is checked.
}
可以看出。。。if-else语句的数量已增加。。。如果你想比较比4更多的复选框,或者在4个复选框中比较更多的复选框,它会的。。。这可能会使事情复杂化,因为(很可能)大多数程序员都无法避免它
我还应该提到,由于以下代码,我知道在给定时间选中了多少复选框:
private int GetNumberOfCheckboxesChecked()
{
int NumberofCheckBoxesChecked = 0;
foreach (Control c in groupBox1.Controls)
{
if ((c is CheckBox) && ((CheckBox)c).Checked)
NumberofCheckBoxesChecked++;
}
return NumberofCheckBoxesChecked;
}
private void OneAtLeast(object originalSender)
{
CheckBox tempCB = (CheckBox)originalSender;
if (!CB1.Checked && !CB2.Checked && !CB3.Checked && !CB4.Checked)
{
tempCB.Checked = true;
MessageBox.Show("You must select at least one option!", "Invalid Operation", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
他们还需要始终选中其中一个复选框,因为每个复选框的checkchanged事件调用以下代码:
private int GetNumberOfCheckboxesChecked()
{
int NumberofCheckBoxesChecked = 0;
foreach (Control c in groupBox1.Controls)
{
if ((c is CheckBox) && ((CheckBox)c).Checked)
NumberofCheckBoxesChecked++;
}
return NumberofCheckBoxesChecked;
}
private void OneAtLeast(object originalSender)
{
CheckBox tempCB = (CheckBox)originalSender;
if (!CB1.Checked && !CB2.Checked && !CB3.Checked && !CB4.Checked)
{
tempCB.Checked = true;
MessageBox.Show("You must select at least one option!", "Invalid Operation", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
因此,我的问题是……是否有更好的(或更有效的,或可以减少代码行数)方法根据选中的复选框来做事情?或者我们真的坚持这种方法(或者这种方法的变体)
请注意,在本例中,无论您根据选中的复选框执行什么操作。。。不能简单地“添加”或“附加”。
还应注意的是,开关箱方法或多或少与此方法相同。。。所以这很可能不会有什么不同。它还被您可以创建一个字典映射,将
int
s映射到Action
s或Func
s(或任何其他合适的),然后使用复选框设置整数中的位。计算完整数后,在字典中查找并分派给该方法。这本词典可以草签一次
例如
其中,lookup
先前已初始化(可能是类的静态成员)
lookup=newdictionary();
lookup.Add(0,donothingNoOptions集);
添加(1,DoJustCB1);
添加(2,DoJustCB2);
查找.添加(3,docb1和cb2butnevercb4);
/*等,以获取其他有效选项*/
这也让您有机会对执行的每个函数应用描述性名称,将它们移出到单独的函数中,然后将具有公共功能的区域合并到较小的辅助函数中。我不确定您能对分支的数量做多少。如果逻辑允许,您可以通过嵌套If
语句来处理其中的一些问题。但这只在某些情况下有用,而在另一些情况下更糟
如果你的4个复选框中确实有16个不同的、不相关的选项,那么最好使用开关,或者不信者建议的@Damien\u查找字典。使用开关
或查找时丢失的一件事是可读性,因为您基本上会将复选框值转换为位掩码,并根据最终的“神奇”整数值执行操作。当然,如果复选框实际上是按照您的方式编号的,那么很容易跟踪哪一个是哪一位。但如果名称类似于ApplesCheckBox
,SeedsCheckBox
,SoilCheckBox
,则很难将其与整数位掩码匹配
您可以通过flags枚举获得其中的一部分。例如,背负:
那么
要使用它,例如在交换机中:
switch (option)
{
case CheckboxActions.None:
DoNothingNoOptionsSet();
break;
case CheckBoxActions.DoJustCB1:
DoJustCB1();
break;
case CheckBoxActions.DoJustCB2:
DoJustCB2();
break;
case CheckBoxActions.DoCB1AndCB2ButNeverCB4:
DoCB1AndCB2ButNeverCB4();
break;
}
或者只需设置一个字典
,并将其用作查找
您可以为枚举值使用适当的名称,这样您就可以确切地知道发生了什么,并且复选框的顺序由枚举值CheckboxActions.CheckBox1
到CheckboxActions.CheckBox4
封装。作为奖励,与普通的int
相比,将CheckboxActions
传递给不同的类和方法会获得更多的类型安全性
事实上,在玩这个游戏时,我刚刚了解到可以从同一个枚举中引用枚举值。因此,您可以完全删除魔法值,上述内容将变为(是的,这将编译):
这是一个好问题,但您是否有更具体的用例?复选框的值如何相互作用?我发现很难相信根据4个复选框的值,您有16个完全不同的选项。请注意:您提供的代码将无法工作。对于每个条件,您都需要这样的设置:(CB1.Checked&&CB2.Checked&&CB3.Checked&&CB4.Checked)
,否则您将得到错误的结果。我想说,复选框的值实际上没有太多交互作用。但它对其他组合的作用却大不相同。不过,这个场景并没有涉及数学。@Ulric true,我在写问题时漏掉了这个,对不起!编辑:添加了一段最有可能相关的代码,可能有助于修复该问题。@Kaitlyn无需道歉。如果我们是完美的,那么我们可能会得到更好的报酬这不就是有效地抽象出一个switch语句,并将其移动到与当前方法无关的初始化代码中吗?除非您计划从多个位置执行相同的操作,否则仅使用开关(选项)
?@lc会有什么好处?鉴于目前考虑的组合数量(16)以及将来可能更多,我还是希望将代码移到单独的方法中。因此,我还简化了创建一个开关
,然后在每个分支中只调用一个函数。所有组合都是预期的,并且是允许的,尽管它们都会导致不同的操作。他们也不允许保留任何未选中的复选框
var option = CheckboxActions.None;
if(CB1.Checked) option = option | CheckboxActions.CheckBox1;
if(CB2.Checked) option = option | CheckboxActions.CheckBox2;
if(CB3.Checked) option = option | CheckboxActions.CheckBox3;
if(CB4.Checked) option = option | CheckboxActions.CheckBox4;
switch (option)
{
case CheckboxActions.None:
DoNothingNoOptionsSet();
break;
case CheckBoxActions.DoJustCB1:
DoJustCB1();
break;
case CheckBoxActions.DoJustCB2:
DoJustCB2();
break;
case CheckBoxActions.DoCB1AndCB2ButNeverCB4:
DoCB1AndCB2ButNeverCB4();
break;
}
[Flags]
enum CheckboxActions
{
None = 0,
CheckBox1 = 1,
CheckBox2 = 2,
CheckBox3 = 4,
CheckBox4 = 8,
DoJustCB1 = CheckboxActions.CheckBox1,
DoJustCB2 = CheckboxActions.CheckBox2,
DoCB1AndCB2ButNeverCB4 = CheckboxActions.CheckBox1 | CheckboxActions.CheckBox2
}