简体   繁体   中英

Distinguish which radio buttons are selected in WinForm C#

I've been working on this for a while but can't quite figure it out. Basically it's a color mixing program with multiple radio buttons, the problem is when blue1 and blue 2 are both selected the formbackground is supposed to change to blue. It changes to purple because of the code below it. Is there anyway to prioritize code via like the try/finally, OrElse statements here?

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void mixrButton_Click(object sender, EventArgs e)
    {
        if (red1.Checked && red2.Checked)
        {
            this.BackColor = Color.Red;
        }
        if (blue1.Checked && blue2.Checked)
        {
            this.BackColor = Color.Blue;
        }
        if (yellow1.Checked && yellow2.Checked)
        {
            this.BackColor = Color.Yellow;
        }

        if ((red1.Checked || blue1.Checked) && (red2.Checked || blue2.Checked))
        {
            this.BackColor = Color.Purple;
        } 

        if ((red1.Checked || yellow1.Checked) && (red2.Checked || yellow2.Checked))
        {
            this.BackColor = Color.Orange;
        }

        if ((blue1.Checked || blue2.Checked) && (yellow1.Checked || yellow2.Checked))
        {
            this.BackColor = Color.Green;
        }            
    }

    private void clear_Click(object sender, EventArgs e)
    {
        this.BackColor = SystemColors.Control;
    }
}

在此输入图像描述

Your main problems here are:

  • the fact that you did not use if/else
  • and the fact that your Purple logic is wrong

Here, even if you did not use else statement, you should have blue, but you are saying that it will be Purple if ((red1.Checked || blue1.Checked) && (red2.Checked || blue2.Checked)) that is to say if

  • red1 & red2 (should be red...)
  • red1 & blue2 (here purple is okay...)
  • blue1 & red2 (here purple is okay...)
  • blue1 & blue2 (should be blue...)

Here is a possible implementation of the color you want:

private void mixrButton_Click(object sender, EventArgs e)
{
    if (red1.Checked && red2.Checked)
    {
        this.BackColor = Color.Red;
    }
    else if (blue1.Checked && blue2.Checked)
    {
        this.BackColor = Color.Blue;
    }
    else if (yellow1.Checked && yellow2.Checked)
    {
        this.BackColor = Color.Yellow;
    }
    else if ((red1.Checked && blue2.Checked) || (blue1.Checked && red2.Checked))
    {
        this.BackColor = Color.Purple;
    } 
    else if ((red1.Checked && yellow2.Checked) || (yellow1.Checked && red2.Checked))
    {
        this.BackColor = Color.Orange;
    }
    else if ((blue1.Checked && yellow2.Checked) || (yellow1.Checked && blue2.Checked))
    {
        this.BackColor = Color.Green;
    }
}

You could also create a function returning the Backcolor and use if and return , or use an approach using the 1st color then the 2nd one

It's not very beautiful, but you could also just swap the order of your statements and put the first three (stricter) below the second three (less strict). That way the stricter ones will override the less strict ones and you should be getting the expected result.

I still don't like it cause of running unnecessary code, but it's an option. edit: imho, the suggested "else if" solution is better.

As others have commented, your conditions are ambiguous which can be fixed with the application of even more logic in the if blocks.

BUT - any time I see a pile of if/then statements like that I take a step back and ask if I should be approaching the problem in a different way, because ploughing through that logic quickly becomes unreadable and unmaintainable.

For a different implementation (of only the 3 colours you have), I would do something like this off the top of my head, which reduces the amount of logic to go through and puts the colour changing code in one place rather than scattering it through the code:

// declaration
[Flags] 
enum ScreenColors 
{
    None = 0,
    Red = 1,
    Yellow = 2,
    Blue = 4 
}

private void button1_Click(object sender, EventArgs e)
{
    ScreenColors selectedColors = ScreenColors.None;

    if (red1.Checked || red2.Checked)
    {
        selectedColors |= ScreenColors.Red;
    }       
    // etc for yellow, blue

    // now I have a flags enum with only the 2 colours I care about

    // so I can build a lookup table that says what combinations of source colors maps to what destination

    Dictionary<ScreenColors, Color> lookups = new Dictionary<ScreenColors, Color>()
    {
        {ScreenColors.Red, Color.Red},
        {ScreenColors.Yellow, Color.Yellow},
        {ScreenColors.Blue, Color.Blue},
        {ScreenColors.Red | ScreenColors.Blue, Color.Purple},
        {ScreenColors.Red | ScreenColors.Yellow, Color.Orange},
        {ScreenColors.Blue | ScreenColors.Yellow, Color.Green},
    };

    //... and now all I have to do is look up the flags in the dictionary to get the correct background
    this.BackColor = lookups[selectedColors];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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