Using Color with Windows Forms

Using Color with Windows Forms

Colors in the .NET Framework are based on four components. In addition to the three primary colors of red, green, and blue, a fourth value, called the alpha component, is used to specify the transparency of the color. Each of the four components is a single byte, which permits values between 0 and 255. In this section, we’ll look at the various classes and structures that are used to work with color when programming with GDI+.

Creating Color Structures

Colors are represented in GDI+ by the Color structure, and when classes and methods work with colors, they work with an instance of the Color structure. The simplest approach to creating a Color instance is to create a named color through a static property. The Color structure exposes 140 named colors through static properties that return prebuilt Color objects. You create a Color value initialized to one of the named colors, like this:

Color newColor = Color.Red; 

There isn’t space to list all 140 colors here, but the complete list of 140 colors is available in the MSDN online help, as well as through Microsoft IntelliSense when you’re writing code with the Code Editor. All of the common color names such as Red, Green, Blue, and Orange are included, as are more exotic names such as MintCream and PapayaWhip. In addition, the Transparent property returns a Color structure that has the alpha component set to 0, resulting in a transparent color.

Another way to create a Color instance is to invoke the static FromArgb method. There are four versions of this method. The first version accepts the four components that make up a Color object as parameters, as shown here:

Color sky = Color.FromArgb(100, 200, 200, 255);

The first parameter is the alpha component, followed by the red, green, and blue (RGB) components.

A second, commonly used version of the FromArgb method, shown in the following code, accepts only the three RGB color components and implicitly sets the alpha component to its maximum value, resulting in a fully opaque color:

Color sky = Color.FromArgb(200, 200, 255);

The third version of FromArgb is used to create a new Color instance from an existing Color object while changing only the alpha component, as shown here:

Color sky = Color.FromArgb(100, Color.PowderBlue); 

This version of FromArgb is used later in this chapter, in the section “Creating Solid Brushes,” to create a brush that provides a transparent blue wash over the client area.

The fourth and final version of the FromArgb method is used to create an instance of Color from a packed integer in the form AARRGGBB, as shown here:

Color sky = Color.FromArgb(0x64C8C8FF); 

Color objects also can be created by calling the static FromKnownColor method. This method accepts a parameter from the KnownColor enumeration, which is discussed later in this chapter, in the section “Using the Current System Colors.” The FromKnownColor method is used as follows:

Color sky = Color.FromKnownColor(KnownColor.PowderBlue); 

Another way to create a Color object is to invoke the static FromName method. This method accepts a string parameter that must contain the name of a value from the KnownColor enumeration, as shown here:

Color sky = Color.FromName("PowderBlue");
Using Color Properties

The Color structure exposes the following four read-only properties that can be used to extract the component parts of a color:

  • A  Returns the alpha component of the color

  • R  Returns the red component of the color

  • G  Returns the green component of the color

  • B  Returns the blue component of the color

You can use these properties to extract the individual components in order to blend new colors, as shown here:

Color sky = Color.FromArgb(Color.PowderBlue.A/2,
                           Color.PowderBlue.R,
                           Color.PowderBlue.G,
                           Color.PowderBlue.B); 

This code extracts the individual component colors and uses the FromArgb method to create a new color that’s slightly more transparent by reducing the value of the alpha component.

Other useful non-static properties exposed by the Color structure include the following:

  • IsNamedColor  Boolean value that’s true if the color value is one of the 140 named colors; otherwise, it’s false.

  • IsKnownColor  Boolean value that’s true if the color value is one of the colors from the KnownColors enumeration; otherwise, it’s false.

  • IsSystemColor  Boolean value that’s true if the color value is one of the property values from the SystemColors class; otherwise, it’s false.

Using the Current System Colors

The Windows user interface enables the user to change predefined colors for elements with a Windows application. Through the Display Properties dialog box, the user can change many of the colors used for standard Windows elements, such as the color of the title bar, the color of windows, and the color of controls. This flexibility for users can make life difficult for application developers. For example, if you choose to display text or figures in a specific color, users who have redefined their color schemes might have difficulty using your application. For this reason, it’s a good idea to take advantage of the user’s color preferences whenever possible.

The SystemColors class encapsulates 26 system colors that are subject to modification by the user. This class provides access to colors via static properties, like this:

Color textColor = SystemColors.WindowText;

This code retrieves the user’s preferred color for window text, whether it’s Black, BurlyBrown, or AntiqueWhite. Table 14-3 lists the static SystemColors properties.

The KnownColor enumeration includes values that encompass the 26 colors exposed as static properties from the SystemColors class, as well as all 141 colors (including Transparent) that are exposed through static properties from the Color structure. A KnownColor value isn’t more space-efficient than a Color value—they’re both 32-bit values.

As mentioned, the Color structure includes the static FromKnownColor method, which can be used to translate a value from the KnownColor enumeration into a Color instance, as shown here:

Color textColor = Color.FromKnownColor(KnownColor.WindowText);
The Color Common Dialog Box

The Color common dialog box is included with every Windows installation. As with the File Open and File Save common dialog boxes discussed in Chapter 13, the Color common dialog box provides a common user interface for a fairly complex task. By leveraging the common dialog boxes in your application, you make life easier for the users of your application and you get a great deal of functionality with just a few lines of code. The basic Color dialog box is shown in Figure 14-2.

Figure 14-2.
The basic form of the Color dialog box before expansion.

This dialog box enables the user to select from an array of predefined colors presented in the palette. The user can also expand the dialog box, as shown in Figure 14-3, which provides a wider selection of colors.

Figure 14-3.
The Color common dialog box after expansion.

To display the Color common dialog box in its fully expanded state from the outset, set the FullOpen property to true, as shown here:

ColorDialog dlg = new ColorDialog();
dlg.FullOpen = true;

You interact with the Color common dialog box through the ColorDialog class, which works much like any other dialog box that’s created in a Windows Form application, as shown here:

System.Windows.Forms.TextBox textBox;

    

ColorDialog dlg = new ColorDialog();
dlg.Color = textBox.BackColor;
if(dlg.ShowDialog() == DialogResult.OK)
{
    textBox.BackColor = dlg.Color;
    
    

As shown in this example, the color selected by the user is retrieved through the Color property. The Color property is also set before the dialog box is invoked, which enables the Color common dialog box to display the current color selection to the user. This is a common design pattern that improves the user’s experience and often makes it much easier for the user to select a desirable color. For example, if the user wants to select a lighter or darker color, it’s helpful to display the current color.

The current set of custom colors also can be preserved and passed to the dialog box before it’s opened. The custom colors are exposed as the CustomColors property, which is typed as an array of integers. To retrieve the current set of custom colors, use code such as this:

int [] _customColors = null;

    

ColorDialog dlg = new ColorDialog();
if(dlg.ShowDialog() == DialogResult.OK)
{
    _customColors = dlg.CustomColors; 
} 

To set the custom colors shown in the dialog box using custom colors that have been previously saved, set the CustomColors property before the dialog box is displayed, as shown here:

int [] _customColors = null;

    

ColorDialog dlg = new ColorDialog();
dlg.CustomColors = _customColors;
if(dlg.ShowDialog() == DialogResult.OK)
{
    
    

The companion CD includes an enhancement to the SimpleEdit project initially created in Chapter 13. This version adds the capability for the user to change the colors of the client area and font. New menu items such as Background Color and Foreground Color have been added to the View menu. The Click event handlers for the new methods are shown here:

private void viewBackgroundMenuItem_Click(object sender, 
                                          System.EventArgs e)
{
    ColorDialog dlg = new ColorDialog();
    dlg.CustomColors = _customColors;
    dlg.Color = textBox.BackColor;
    if(dlg.ShowDialog() == DialogResult.OK)
    {
        textBox.BackColor = dlg.Color;
        _customColors = dlg.CustomColors;
    }
}

private void viewForegroundMenuItem_Click(object sender,
                                          System.EventArgs e)
{
    ColorDialog dlg = new ColorDialog();
    dlg.CustomColors = _customColors;
    dlg.Color = textBox.ForeColor;
    if(dlg.ShowDialog() == DialogResult.OK)
    {
        textBox.ForeColor = dlg.Color;
        _customColors = dlg.CustomColors;
    }
}

Both event handlers work in similar ways. First the ColorDialog object is instantiated, and then the current color context is passed to the dialog box’s CustomColors and Color properties. If the user clicks OK to dismiss the dialog box, the appropriate color property for the textBox object is modified and the current set of custom colors is cached.



Part III: Programming Windows Forms