简体   繁体   English

减少Windows窗体清单列表中的else系列C#

[英]Reduce if else series in windows form checkedlistbox c#

In c#, in my windows form, I use a checkedListBox. 在C#中,在Windows窗体中,我使用了一个checkedListBox。 So far in my checkedListBox I have 3 items. 到目前为止,在我的checkedListBox中,我有3个项目。 And 3 series of if/elseif statement. 和3系列的if / elseif语句。

I would like to implement a neat way of having specific actions depending on the combination of the items chosen. 我想采用一种巧妙的方式,根据所选项目的组合采取具体措施。 I was thinking on a binary tree. 我在想一棵二叉树。

Is a binary tree okay, or is there a method/property I do not know about in the checkedListBox that can help me? 二叉树可以吗,或者在checkListListBox中有我不知道的方法/属性可以帮助我?

Below is the current code : 下面是当前代码:

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);
        }
    }

Given you have multiple selections in checkbox list. 鉴于您在复选框列表中有多个选择。 You can try implementing Strategy pattern for this problem. 您可以尝试针对此问题实施策略模式。 Basically you need to create a strategy for each variant. 基本上,您需要为每个变体创建策略。 You can read more on this here . 您可以在此处阅读更多内容。

By implementing this you will be following the open close principle which means no matter how many items you wan to add later, your existing code will not need modification but will be open for extension. 通过实现这一点,您将遵循开放关闭原则,这意味着无论以后要添加多少项,您现有的代码都不需要修改,而是可以扩展。

First create yourself an enum like this: 首先创建一个这样的枚举:

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

Now on your action event you fill in an instance of your demo enum thus: 现在,在您的动作事件中,您可以填写演示枚举的实例,从而:

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;
}

Now you can have a switch statement so: 现在您可以拥有一个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;
}

This illustrates the use of "OR"-ing items together. 这说明了“或”项一起使用。 From three options, you can get 8 possibilities (2^3). 从三个选项中,您可以获得8种可能性(2 ^ 3)。 All you need to do, is to make sure your "Principle" options are powers of two within your enumeration. 您需要做的就是确保您的“原理”选项是枚举中的2的幂。

EDIT 编辑

Strongly related to this use of powers of 2 within an enum, is the flags attribute. 标志属性与与此枚举中2的幂的使用紧密相关。 For example: 例如:

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

This allows you to create an instance of the enum in the same way as before, but now you can use the syntax: 这允许您以与以前相同的方式创建枚举的实例,但是现在您可以使用以下语法:

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

Depending on your circumstances, this might be more useful. 根据您的情况,这可能会更有用。

I would suggest that you introduce a flag enum that represents the items in the CheckedListBox . 我建议您引入一个标志枚举,它表示CheckedListBox的项目。

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

Then create the items for the CheckedListBox based on these enum values: 然后根据以下枚举值为CheckedListBox创建项目:

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

The binding to the Action to be performed based on these flags is encapsulated in a class: 基于这些标志与要执行的Action的绑定封装在一个类中:

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; }
}

You initialize a list of these actions and the criteria when they shall be performed. 您可以初始化这些动作和条件的清单。

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

You can give combinations of conditions by combining flags, eg 您可以通过组合标志来提供条件组合,例如

Condition = ActionItemToPerform.ActionItem0 & ActionItemToPerform.ActionItem1

When you read the checked items, create the cumulative flag state tally and compare with the configured actions: 当您读取选中的项目时,请创建累积标志状态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);
        }
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM