Click here to Skip to main content
15,860,859 members
Articles / Desktop Programming / Windows Forms
Article

A DateTimePicker with working BackColor

Rate me:
Please Sign up or sign in to vote.
4.84/5 (28 votes)
3 Nov 2008CPOL3 min read 210.6K   8.6K   59   37
A DateTimePicker derived class showing the background color we want.

Image 1

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:

C#
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:

C#
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.

C#
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.

C#
[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

C#
[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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead
Italy Italy
I'm a graduate in Computer Science.
I work with Metatrader MQL4,MQL5 / C# / Asp.Net / Windows Forms / SQL Server / Access / VBA / HTML / CSS / Javascript / classic C/C++.


I also like writing songs and playing around with my band Diversamente Rossi.
This is the video of the song Un'altra estate from the album L'immobile disegno.



"Short code, good code"

Comments and Discussions

 
GeneralRe: Cool. What if I want to set the border of the control? Pin
dave.toland7-Mar-12 1:07
dave.toland7-Mar-12 1:07 
GeneralKool control Pin
Donsw20-Jan-09 5:56
Donsw20-Jan-09 5:56 
GeneralRe: Kool control Pin
Vincenzo Rossi20-Jan-09 10:34
professionalVincenzo Rossi20-Jan-09 10:34 
GeneralRe: Kool control Pin
Donsw20-Jan-09 14:31
Donsw20-Jan-09 14:31 
GeneralRe: Kool control Pin
Nitin S10-Dec-09 22:48
professionalNitin S10-Dec-09 22:48 
QuestionException Thrown Pin
verdant726-Dec-08 8:29
verdant726-Dec-08 8:29 
AnswerException Thrown - HOW TO FIX ! Pin
Vincenzo Rossi29-Dec-08 12:48
professionalVincenzo Rossi29-Dec-08 12:48 
GeneralDemo not compiling Pin
colkaih24-Nov-08 22:55
colkaih24-Nov-08 22:55 
Tried loading up this example in VS2008 /Framework 3.5 SP1 and once the project had converted, it listed an error for every date time picker control.
Tried adding just the .cs file to a project but then there is no obvious way to actually add a control to the form via the designer. Should the code actually be made into a DLL first?
AnswerRe: Demo not compiling Pin
Vincenzo Rossi27-Nov-08 10:19
professionalVincenzo Rossi27-Nov-08 10:19 
GeneralThanks! Pin
tehtb3-Nov-08 23:12
tehtb3-Nov-08 23:12 
JokeRe: Thanks! Pin
Vincenzo Rossi4-Nov-08 5:14
professionalVincenzo Rossi4-Nov-08 5:14 
GeneralVery nice solution Pin
Mark.Whitfeld3-Nov-08 21:44
Mark.Whitfeld3-Nov-08 21:44 
GeneralRe: Very nice solution Pin
Vincenzo Rossi4-Nov-08 6:21
professionalVincenzo Rossi4-Nov-08 6:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.