减少 windows 表单中的 if else 系列 checkedlistbox c#

Reduce if else series in windows form checkedlistbox c#

在 c# 中,在我的 windows 表单中,我使用了一个 checkedListBox。 到目前为止,在我的 checkedListBox 中我有 3 个项目。 以及 3 系列的 if/elseif 语句。

我想实现一种巧妙的方法,根据所选项目的组合执行特定操作。 我在考虑二叉树。

二叉树可以吗,或者checkedListBox中有我不知道的method/property可以帮助我吗?

以下是当前代码:

private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        if (checkedListBox1.GetItemCheckState(0) == CheckState.Checked)
        {
            do_action_item0(current_parameters);
        }
        else if(checkedListBox1.GetItemCheckState(0) != CheckState.Checked)
        {
            undo_action_item0(previous_parameters);
        }

        if (checkedListBox1.GetItemCheckState(1) == CheckState.Checked)
        {
            do_action_item1(current_parameters);
        }
        else if (checkedListBox1.GetItemCheckState(1) != CheckState.Checked)
        {
            undo_action_item1(previous_parameters);
        }

        if (checkedListBox1.GetItemCheckState(2) == CheckState.Checked)
        {
            do_action_item2(current_parameters);
        }
        else if (checkedListBox1.GetItemCheckState(2) != CheckState.Checked)
        {
            undo_action_item2(previous_parameters);
        }
    }

鉴于您在复选框列表中有多项选择。您可以尝试针对此问题实施策略模式。基本上,您需要为每个变体创建一个策略。您可以在 here.

上阅读更多内容

通过实施这个,您将遵循开闭原则,这意味着无论您以后要添加多少项目,您现有的代码都不需要修改,但将开放以供扩展。

首先像这样为自己创建一个枚举:

public enum demo 
{
    none = 0,
    AOnly = 1,
    BOnly = 2,
    AandB = 3,
    COnly = 4,
    AandC = 5,
    BandC = 6,
    ABC = 7
}

现在,在您的动作事件中,您填写一个演示枚举的实例:

demo myDemo = demo.none;

if (checkedListBox1.CheckedItems.Contains("Option A"))
{
    myDemo = myDemo | demo.AOnly;
}
if (checkedListBox1.CheckedItems.Contains("Option B"))
{
    myDemo = myDemo | demo.BOnly;
}
if (checkedListBox1.CheckedItems.Contains("Option C"))
{
    myDemo = myDemo | demo.COnly;
}

现在你可以有一个 switch 语句:

switch (myDemo)
{
    case demo.AOnly:
        MessageBox.Show("A Only");
        break;
    case demo.BOnly:
        MessageBox.Show("B Only");
        break;
    case demo.COnly:
        MessageBox.Show("C Only");
        break;
    case demo.AandB:
        MessageBox.Show("A and B");
        break;
    case demo.AandC:
        MessageBox.Show("A and C");
        break;
    case demo.BandC:
        MessageBox.Show("B and C");
        break;
    case demo.ABC:
        MessageBox.Show("ABC");
        break;
}

这说明了 "OR"-ing 项目的使用。从三个选项中,您可以获得 8 种可能性 (2^3)。您需要做的就是确保您的 "Principle" 选项在您的枚举中是 2 的幂。

编辑

与在枚举中使用 2 的幂密切相关的是 flags 属性。例如:

[FlagsAttribute]
public enum demo2 
{
    none = 0,
    A = 1,
    B = 2,
    C = 4
}

这允许您以与以前相同的方式创建枚举实例,但现在您可以使用语法:

bool hasOptB = myDemo.HasFlag(demo2.B);

根据您的情况,这可能更有用。

我建议您引入一个代表 CheckedListBox 中项目的标志枚举。

[Flags]
enum ActionItemToPerform {
    None = 0, ActionItem0 = 1, ActionItem1 = 2, ActionItem2  = 4
}

然后根据这些枚举值为 CheckedListBox 创建项目:

CheckedListBox clb = new CheckedListBox();
foreach(var possibleAction in Enum.GetValues(typeof(ActionItemToPerform))){
   clb.Items.Add(possibleAction, false);
}

根据这些标志对要执行的动作的绑定封装在class:

public class ConditionalDoAction {

    // initialize this with the conditions when this shall be performed 
    public ActionItemToPerform Condition { get; set; }

    // TODO: tweak delegate to match your method signatures...
    public Action<CurrentParameters> Do { get; set; }
}

您初始化这些操作的列表以及执行它们的条件。

var configuredActions = new List<ConditionalDoAction>();
configuredActions.Add(new ConditionalDoAction  {
    Condition = ActionItemToPerform.ActionItem0,
    Do =  do_action_item0
});

您可以通过组合标志给出条件组合,例如

Condition = ActionItemToPerform.ActionItem0 & ActionItemToPerform.ActionItem1

当您阅读检查项目时,创建累积标志状态tally并与配置的动作进行比较:

btn.Click += delegate {
    ActionItemToPerform tally = ActionItemToPerform.None;
    foreach (var selectedAction in clb.CheckedItems) {
        tally |= selectedAction;
    }

    foreach(var configuredAction in configuredActions) {
        if (configuredAction.HasFlag(tally)) {
            configuredAction.Do(current_parameters);
        }
    }
};