Use scrollbars to select RGB and HLS colors in C#

Datetime:2016-08-22 22:14:16          Topic: C#           Share

The example Convert between RGB and HLS color models in C# explains how to convert between the RGB and HLS color models. This example uses similar code to let the user manipulate scroll bars to select colors using either model.

Drag the scroll bars back and forth to adjust the color selected and to see how the result affects the other color model’s values. For example, it’s interesting to see how the R, G, and B components change as you drag the H component back and forth.

See the earlier example to view the code that converts between the two color models. This example is actually pretty simple. The most interesting new feature is the different way in which the two programs handle events.

The previous example uses the following code to select a color using one of the color component controls.

// The selected color.
private Color SelectedColor;

// True while we're setting the color.
private bool IgnoreEvents = false;

// Select a color from the RGB values.
private void SelectRGBColor()
{
    if (IgnoreEvents) return;
    IgnoreEvents = true;

    // Save the selected color and display a sample.
    int R = (int)nudR.Value;
    int G = (int)nudG.Value;
    int B = (int)nudB.Value;
    SelectedColor = Color.FromArgb(R, G, B);
    picSample.BackColor = SelectedColor;

    // Convert to HLS.
    double H, L, S;
    ColorStuff.RgbToHls(R, G, B, out H, out L, out S);

    // Display HLS values.
    txtH.Text = H.ToString("0.00");
    txtL.Text = L.ToString("0.00");
    txtS.Text = S.ToString("0.00");

    IgnoreEvents = false;
}

// Select a color from the HLS values.
private void SelectHLSColor()
{
    if (IgnoreEvents) return;
    IgnoreEvents = true;

    try
    {
        // Convert into RGB.
        double H = double.Parse(txtH.Text);
        double L = double.Parse(txtL.Text);
        double S = double.Parse(txtS.Text);
        int R, G, B;
        ColorStuff.HlsToRgb(H, L, S, out R, out G, out B);

        // Display RGB values.
        nudR.Value = (decimal)R;
        nudG.Value = (decimal)G;
        nudB.Value = (decimal)B;

        // Save the selected color and display a sample.
        SelectedColor = Color.FromArgb(
            (int)nudR.Value,
            (int)nudG.Value,
            (int)nudB.Value);
        picSample.BackColor = SelectedColor;
    }
    catch
    {
    }
    IgnoreEvents = false;
}

When the user changes the R, G, or B value, the code calls SelectRGBColor to define the color using those values. When the user changes the H, L, or S value, the code calls SelectHLSColor to define the color using those values.

The program uses the variable IgnoreEvents to prevent the controls from creating recursive calls. For example, suppose you change the R value so the code calls SelectRGBColor . That method sets the values of the H, L, and S TextBox controls. Their TextChanged event handlers would then execute and call the SelectHLSColor method. That method sets the R, G, and B values, which fire their events calling SelectRGBColor , and the whole thing starts over again. The result is an infinite series of events that uses up the program’s call stack causing the program to crash.

Try removing the IgnoreEvents variable and see what happens when you change the R value a couple of times.

The program uses the IgnoreEvents variable to prevent this infinite cascade of events. If it is already handling an event, the code ignores change events from the other controls.

Now back to the new example. This example executes the following code when you change the R, G, or B value. The code that handles the H, L, and S values is similar.

// Select a new RGB color.
private void scrRGB_Scroll(object sender, ScrollEventArgs e)
{
    // Save the selected color and display a sample.
    int R = scrR.Value;
    int G = scrG.Value;
    int B = scrB.Value;
    picSample.BackColor = Color.FromArgb(R, G, B);

    // Convert to HLS.
    double H, L, S;
    ColorStuff.RgbToHls(R, G, B, out H, out L, out S);

    // Display HLS values.
    scrH.Value = (int)H;
    scrL.Value = (int)(L * 1000);
    scrS.Value = (int)(S * 1000);

    ShowNumericValues(R, G, B, H, L, S);
}

Notice that this code doesn’t use an IgnoreEvents variable. Using that variable wouldn’t hurt but it isn’t necessary in this case because of a peculiarity of the HScrollBar and VScrollBar controls. Those controls have two events that can occur when their values change: Scroll and ValueChanged . The Scroll event occurs when the user changes the ScrollBar ‘s value. The ValueChanged event occurs whenever the ScrollBar ‘s value changes whether it was changed by the user or by code.

This example uses the Scroll event. When the code shown here sets another ScrollBar ‘s value, that control’s Scroll event doesn’t fire because the user isn’t changing the value, so there is no cascading series of events.





About List