Using Up-Down Controls

Using Up-Down Controls

Up-down controls are commonly used in Windows Forms applications to enable the user to select from a range of incrementing values. An up-down control couples a TextBox control with a small scroll bar that’s used to increment and decrement the contents of the TextBox control.

The UpDownBase class serves as an abstract base class for the two up-down control implementations provided in the System.Windows.Forms namespace.

  • NumericUpDown  Enables the user to increment and decrement decimal values in a TextBox control

  • DomainUpDown  Enables the user to iterate over an array of objects that are represented as strings

Two commonly used properties are defined by the UpDownBase class.

  • ReadOnly  A Boolean value that specifies whether the contents of the control are read-only. If true, the contents of the control can be changed only by using the up and down arrows.

  • UpDownAlign  A value from the LeftRightAlignment enumeration (LeftRightAlignment.Left or LeftRightAlignment.Right) that specifies the positioning of the up and down arrows.

The following subsections describe the concrete controls that are derived from the UpDownBase class. The NumericUpDown and DomainUpDown controls have the same outward appearance and basic operation; however, they extend the base control in different ways to add functionality.

The NumericUpDown Control

The NumericUpDown control, the most common form of up-down control, is used to increment a numeric value that’s displayed in the text box. The Numeric­UpDown control works with decimal values instead of integers; using the decimal type makes it possible to increment values that aren’t whole numbers.

The current value of the control is obtained through the Value property, as shown here:

int age = Convert.ToInt32(ageUpDown.Value);

Because the NumericUpDown control works with decimal values, you must explicitly convert the Value property to an integer.

By default, the NumericUpDown control will display only whole-number values. To enable the display of floating-point values, you must specify the desired precision with the DecimalPlaces property, like this:

ageUpDown.DecimalPlaces = 3;

This example causes the control to display three decimal places to the right of the decimal point.

By default, values allowed by the NumericUpDown control will range from 0 through 100. These limits are changed with the Minimum and Maximum properties, as shown in the following code:

interestRateUpDown.Minimum = 4.55M;
interestRateUpDown.Maximum = 12.35M;

In most cases, you’ll want to increment and decrement values in the control by 1, and this is the default setting. The Increment property is used to modify the rate of change for the control, as shown here:

interestRateUpDown.Increment = 0.1M;

When the value stored in the NumericUpDown control is changed using the up and down arrows, the ValueChanged event is raised. You can handle this event to take action when the contents of the control have been updated, as shown here:

private void interestRateUpDown_ValueChanged(object sender,
                                             System.EventArgs e)
{
    _rate = interestRateUpDown.Value;
    statusLabel.Text = string.Format("The current interest rate is {0}",
                                     _rate);
}

If the user enters a new value directly into the control, the ValueChanged event won’t be raised; instead, you’ll see a TextChanged event. If the control’s ReadOnly property isn’t set to true, you should handle this event as shown in the following code:

private void interestRateUpDown_TextChanged(object sender,
                                            System.EventArgs e)
{
    _rate = interestRateUpDown.Value;
    statusLabel.Text = string.Format("The current interest rate is {0}",
                                     _rate);
}
The DomainUpDown Control

The DomainUpDown control enables any collection of objects to be used as the underlying items in an up-down control. Each item in the collection must have a string representation, which means either that you’re storing a collection of string objects or that each of your objects implements the ToString method.

For example, consider a simple Sailboat class, such as the one shown here (with the non-essential methods and fields filtered out):

public class Sailboat
{
    string _name;
    
    

    public Sailboat(string name)
    {
        _name = name;
    }
    
    

    public override string ToString()
    {
        return _name;
    }
}

Because the Sailboat class overrides the ToString method to return the name of the sailboat, an array of Sailboat objects can be placed into a DomainUpDown control, using code such as this:

Sailboat [] boats = new Sailboat [] {
                                       new Sailboat("Pegasus"),
                                       new Sailboat("Sayonara"),
                                       new Sailboat("Stars 'n Stripes"),
                                       new Sailboat("Black Magic")
                                    };
domainUpDown.Items.AddRange(boats);

Because the DomainUpDown control works with collections of objects instead of decimal values, it doesn’t use the Value property exposed by the NumericUpDown control. Instead, the following two properties are exposed for retrieving the currently selected object:

  • SelectedIndex  Identifies the index of the currently selected item

  • SelectedItem  Identifies a reference to the currently selected item

The ColorUpDown application, on the companion CD, is an example project that fills a DomainUpDown control with the names of values from the KnownColor enumeration. (See the Microsoft Developer Network [MSDN] Library for a list of members.) When the user selects a new color, the client area of the form is changed to use the new color. The relevant code is shown here:

public class MainForm : System.Windows.Forms.Form
{
    
    

    public MainForm()
    {
        
    

        string [] colorNames = Enum.GetNames(typeof(KnownColor));
        knownColorUpDown.Items.AddRange(colorNames);
        knownColorUpDown.SelectedIndex = 0;
    }
    
    

    private void knownColorUpDown_SelectedItemChanged(object sender,
                                                     System.EventArgs e)
    {
        string currentColorName = (string)knownColorUpDown.SelectedItem;
        try
        {
            BackColor = Color.FromName(currentColorName);
        }
        catch(ArgumentException exception)
        {
            MessageBox.Show(exception.Message);
        }
    }
}

The handler for the SelectedItemChanged event catches the Argument­Exception exception to handle a specific case. One of the members of the KnownColor enumeration is KnownColor.Transparent, and the form’s BackColor property can’t be set to this value.



Part III: Programming Windows Forms