Click here to Skip to main content
15,888,351 members
Articles / Programming Languages / C#
Article

Nullable DateTimePicker

Rate me:
Please Sign up or sign in to vote.
4.84/5 (41 votes)
17 Nov 2003 417.7K   18.2K   54   60
A standard DateTimePicker control that enables users to enter null value. The fact that it's not intensively modified ensures that it has no potential errors.

Sample Image - Nullable_DateTimePicker.jpg

Introduction

I had do a research on a DateTimePicker that could enter null value and found a lot of solutions to it. But one major problem with those is that they behave quite different from the standard ones and may have many potential bugs, as a result it took time to test before using in a real application. I just found another simple solution that could solve this problem with a little modification, so it could promise no bugs :-).

Solution

I have overridden the Value property to accept Null value as DateTime.MinValue, while maintaining the validation of MinValue and MaxValue of the standard control. That's all there's to it.

Because it's so simple, there's not much to say about it. Please refer to code for details.

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


Written By
Vietnam Vietnam
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
PraiseSimple is beautiful! Pin
ineedajobsoon4-Mar-16 2:54
ineedajobsoon4-Mar-16 2:54 
QuestionNullable DateTimePicker Pin
Member 1174358825-Jun-15 20:47
Member 1174358825-Jun-15 20:47 
QuestionKhông sử dụng được Custom Format Pin
Do Cao Tri13-Dec-14 5:25
Do Cao Tri13-Dec-14 5:25 
QuestionNot work anymore ? Pin
duonglei16-Jun-14 22:20
duonglei16-Jun-14 22:20 
QuestionData Binding Pin
wiggles30-May-14 5:50
wiggles30-May-14 5:50 
QuestionProblem with this control Pin
MarkRyan19811-Jan-14 23:53
MarkRyan19811-Jan-14 23:53 
QuestionNot able to download the Source Files Pin
hdng7631-Oct-12 5:00
hdng7631-Oct-12 5:00 
QuestionHow easy is that!! Pin
Woody10022-Sep-12 0:30
Woody10022-Sep-12 0:30 
QuestionJust what I needed Pin
gemini_dk20-Dec-11 4:43
gemini_dk20-Dec-11 4:43 
AnswerRe: Just what I needed Pin
jf6425-Jan-12 4:57
jf6425-Jan-12 4:57 
GeneralNo hour in sql database Pin
cyrilcp9-Nov-10 0:16
cyrilcp9-Nov-10 0:16 
GeneralValidation wrong value fix Pin
PREMSONBABY20-May-10 4:38
PREMSONBABY20-May-10 4:38 
GeneralRe: Validation wrong value fix Pin
oliwan30-Sep-10 12:16
oliwan30-Sep-10 12:16 
Hi,

I added a NullableValue property that allows data binding. I also added some code
to show the user when the control has the focus when the date is null (Nothing in
VB) by showing a "|" which looks almost like a cursor. I also improved the behavior
when the user starts typing in the empty field.

public class NullableDateTimePicker : DateTimePicker
{
	private DateTimePickerFormat _oldFormat = DateTimePickerFormat.Long;
	private string _oldCustomFormat;
	private bool _dateIsNull;

	private bool _isInternalValueChanging;
	public bool IsInternalValueChanging { get { return _isInternalValueChanging; } }

	public NullableDateTimePicker()
		: base()
	{
	}

	[Bindable(true)]
	[Category("Behavior")]
	[Description("The current nullable date/time value for this control")]
	public DateTime? NullableValue
	{
		get
		{
			if (_dateIsNull) {
				return null;
			}
			return base.Value;
		}
		set
		{
			if (value.HasValue) {
				Value = value.Value;
			} else {
				Value = DateTime.MinValue;
			}
		}
	}

	public new DateTime Value
	{
		get
		{
			if (_dateIsNull)
				return DateTime.MinValue;
			else
				return base.Value;
		}
		set
		{

			if (value == DateTime.MinValue) {
				if (!_dateIsNull) {
					_oldFormat = this.Format;
					_oldCustomFormat = this.CustomFormat;
					_dateIsNull = true;
				}

				this.Format = DateTimePickerFormat.Custom;
				this.CustomFormat = this.Focused ? "|" : " ";
				base.OnValueChanged(new EventArgs());
			} else {
				if (_dateIsNull) {
					this.Format = _oldFormat;
					this.CustomFormat = _oldCustomFormat;
					_dateIsNull = false;
				}

				if (value < this.MaxDate && value > this.MinDate) {
					base.Value = value;
				} else if (value > this.MaxDate) {
					value = this.MaxDate;
				} else if (value < this.MinDate) {
					value = this.MinDate;
				}
			}
		}
	}

	protected override void OnCloseUp(EventArgs eventargs)
	{
		base.OnCloseUp(eventargs);

		if (Control.MouseButtons == MouseButtons.None) {
			if (_dateIsNull) {
				_isInternalValueChanging = true;

				this.Format = _oldFormat;
				this.CustomFormat = _oldCustomFormat;
				_dateIsNull = false;

				_isInternalValueChanging = false;
			}
		}
	}

	protected override void OnKeyDown(KeyEventArgs e)
	{
		base.OnKeyDown(e);
		if (e.KeyCode == Keys.Delete) {
			this.Value = DateTime.MinValue;
		} else if (_dateIsNull) {
			_isInternalValueChanging = true;
			if (e.KeyCode == Keys.Space || e.KeyCode == Keys.Up || e.KeyCode == Keys.Down || e.KeyCode == Keys.Right || e.KeyCode == Keys.Left) {
				this.Value = DateTime.Today;
			} else if ((Char.IsNumber((char)e.KeyValue) && e.KeyValue != 48) || (e.KeyValue >= 97 && e.KeyValue <= 105)) { //"0" correction, NumPad1 - NumPad9 
				int typedDigit = 1;
				if (e.KeyValue >= 97 && e.KeyValue <= 105) { //<-- NumPad1 - NumPad9 must be calculated to numeric KeyValues 
					typedDigit = int.Parse(((char)(e.KeyValue - 48)).ToString());
				} else { //if (Char.IsNumber((char)e.KeyValue)) 
					typedDigit = int.Parse(((char)e.KeyValue).ToString());
				}
				this.Value = DateTime.Now;
				SendKeys.SendWait("{RIGHT}"); // Selects the day part
				SendKeys.Send(typedDigit.ToString()); // Replaces the date part by the typed digit
			}
			_isInternalValueChanging = false;
		}
	}

	protected override void OnGotFocus(EventArgs e)
	{
		base.OnGotFocus(e);
		if (_dateIsNull) {
			CustomFormat = "|"; // Show the user that the NullableDateTimePicker has the Focus by simulating a cursor.
		}
	}

	protected override void OnLostFocus(EventArgs e)
	{
		if (_dateIsNull) {
			CustomFormat = " ";
		}
	}
}

--* Oli *--
www.cysoft.ch

GeneralRe: Validation wrong value fix Pin
DeuceDude28-Oct-11 15:46
DeuceDude28-Oct-11 15:46 
Generalthank you for your help! Pin
wuhai08095-May-10 14:52
wuhai08095-May-10 14:52 
GeneralSet Nullable DateTimePicker default value [00/00/0000] Pin
tinhleduc26-Feb-10 0:27
tinhleduc26-Feb-10 0:27 
GeneralUpdate Pin
Romain TAILLANDIER21-Sep-09 22:37
Romain TAILLANDIER21-Sep-09 22:37 
GeneralThis is a very insightful approach to the problem Pin
Phil Raevsky28-Aug-09 16:01
Phil Raevsky28-Aug-09 16:01 
GeneralThis one dispaly pink if null date (VB.NET) Pin
Larry Rouse28-Aug-09 11:32
Larry Rouse28-Aug-09 11:32 
GeneralThis one works! (VB 2008) [modified] Pin
Jeromeyers10-Feb-09 12:55
Jeromeyers10-Feb-09 12:55 
GeneralRe: This one works! (VB 2008) Pin
EMYNA28-Oct-09 12:40
EMYNA28-Oct-09 12:40 
GeneralRe: This one works! (VB 2008) [modified] Pin
Chris Wineinger13-Feb-13 8:31
Chris Wineinger13-Feb-13 8:31 
GeneralUse the Nullable Datetime for a more updated solution. Pin
chstngs7-Oct-08 5:39
chstngs7-Oct-08 5:39 
GeneralIt's really great! Thank you very much!! Pin
wxpwu15-Jun-08 2:48
wxpwu15-Jun-08 2:48 
GeneralSmall correction Pin
Maxxx33316-Nov-06 1:32
Maxxx33316-Nov-06 1:32 

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.