Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

A DateTimePicker with working BackColor

0.00/5 (No votes)
3 Nov 2008 1  
A DateTimePicker derived class showing the background color we want.

Introduction

Some Windows Forms controls in .NET don't allow us to change the BackColor. This is true in the case of DateTimePicker. Another known problem is the poor readability of the text when the controls are disabled. In this example, I have derived such a class introducing the ability to set BackColor, and I've added a new property BackDisabledColor.

Background

The BackColor property is defined in the base class Control, and therefore is available in the derived classes. Also, such a property is usually available in the Properties window at design-time. However, the standard DateTimePicker is not able to draw a user chosen background color. If we set it, nothing happens. So, in the DateTimePicker class, this property is overridden with the attribute [Browsable(false)]. In this way, we don't have to see a useless property.

The DateTimePicker control uses some Windows features to draw the control. So, the WM_PAINT message is not managed by OnPaint method of the class itself. The OnPaint method is never called. To force calling that method in our derived class, we have to set the control style to UserPaint in the constructor:

this.SetStyle(ControlStyles.UserPaint, true);

Now, we can use our OnPaint, but we cannot take advantage of the base OnPaint because it does nothing. To check this, try the following code:

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) {
    base.OnPaint(e);
}

You will see the control showing nothing. So now, we have the entire responsibility of drawing the control. In order to keep a useful and clear code, we abandon two original features otherwise requiring a lot of coding. The first one is the optional checkbox used to allow end-users to skip the displayed date (the ShowCheckBox property). The second is the ability to enter date parts directly using keyboard and not through a calendar.

Using the Code

To use the code, simply add the DateTimePicker.cs file to your project and use the BCDateTimePicker just like its base class.

The main work is done by an override of the OnPaint method. Here, we put the code to draw the background rectangle, filled with the color we want, and then draw the drop down button and the text representing the date. The work of drawing the drop down button is done by ComboBoxRenderer.DrawDropDownButton.

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
    Graphics g = this.CreateGraphics();

    //The dropDownRectangle defines position and size of dropdownbutton block, 
    //the width is fixed to 17 and height to 16. 
    //The dropdownbutton is aligned to right
    Rectangle dropDownRectangle = 
       new Rectangle(ClientRectangle.Width - 17, 0, 17, 16);
    Brush bkgBrush;
    ComboBoxState visualState;

    //When the control is enabled the brush is set to Backcolor, 
    //otherwise to color stored in _backDisabledColor
    if (this.Enabled) {
         bkgBrush = new SolidBrush(this.BackColor);
         visualState = ComboBoxState.Normal;
    }
    else {
        bkgBrush = new SolidBrush(this._backDisabledColor);
        visualState = ComboBoxState.Disabled;
    }

    // Painting...in action

    //Filling the background
    g.FillRectangle(bkgBrush, 0, 0, ClientRectangle.Width, ClientRectangle.Height);
    
    //Drawing the datetime text
    g.DrawString(this.Text, this.Font, Brushes.Black, 0, 2);

    //Drawing the dropdownbutton using ComboBoxRenderer
    ComboBoxRenderer.DrawDropDownButton(g, dropDownRectangle, visualState);

    g.Dispose();
    bkgBrush.Dispose();
}

In order to show the BackColor property in the Properties window again, we override it, setting the Browsable attribute to true.

[Browsable(true)]
public override Color BackColor
{
    get { return base.BackColor; }
    set { base.BackColor = value; }
}

Also, we create a BackDisabledColor property allowing the developer to choose the color at design-time.

BCDateTimePickerProperties.gif

[Category("Appearance"), 
 Description("The background color of the component when disabled")]
[Browsable(true)]
public Color BackDisabledColor
{
    get { return _backDisabledColor; }
    set { _backDisabledColor = value; }
}

Points of Interest

In the overridden OnPaint method, I've created a new Graphics object from the control rather than use the one returned by PaintEventArgs. In fact, when using the ShowUpDown mode, the base class invalidates only the date part region involved by user interaction. When using the long format, this produces an incorrect text display. Since I've found no other way to extend the clipping region of the Graphics object passed by the event argument, the solution adopted is to create a new Graphics, allowing to draw in the whole extent of the control.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here