24

What's the easiest and most robust way of altering the .NET DateTimePicker control, to allow users to enter null values?

Shin
  • 664
  • 2
  • 13
  • 30
GWLlosa
  • 23,995
  • 17
  • 79
  • 116
  • Another option is to use a MaskedTextBox with a mask of `00/00/0000`. This allows somewhat intuitive data entry and probably the most intuitive UX for backing out a date field. – KyleMit Nov 15 '19 at 22:47

6 Answers6

47

You don't need to modify it to do this.

The DateTimePicker in .net actually has a checkbox built-in.

Set the ShowCheckBox property to true.

Then you can use the Checked property to see if the user has entered a value.

http://msdn.microsoft.com/en-us/library/system.windows.forms.datetimepicker.showcheckbox(VS.80).aspx

Himanshu
  • 31,810
  • 31
  • 111
  • 133
Jan Obrestad
  • 763
  • 5
  • 11
6

Here's an approach from this CodeProject article on creating a Nullable DateTimePicker.

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.

Here's a version of the custom class component from the article

public class NullableDateTimePicker : System.Windows.Forms.DateTimePicker
{
    private DateTimePickerFormat originalFormat = DateTimePickerFormat.Short;
    private string originalCustomFormat;
    private bool isNull;

    public new DateTime Value
    {
        get => isNull ? DateTime.MinValue : base.Value;
        set
        {
            // incoming value is set to min date
            if (value == DateTime.MinValue)
            {
                // if set to min and not previously null, preserve original formatting
                if (!isNull)
                {
                    originalFormat = this.Format;
                    originalCustomFormat = this.CustomFormat;
                    isNull = true;
                }

                this.Format = DateTimePickerFormat.Custom;
                this.CustomFormat = " ";
            }
            else // incoming value is real date
            {
                // if set to real date and previously null, restore original formatting
                if (isNull)
                {
                    this.Format = originalFormat;
                    this.CustomFormat = originalCustomFormat;
                    isNull = false;
                }

                base.Value = value;
            }
        }
    }

    protected override void OnCloseUp(EventArgs eventargs)
    {
        // on keyboard close, restore format
        if (Control.MouseButtons == MouseButtons.None)
        {
            if (isNull)
            {
                this.Format = originalFormat;
                this.CustomFormat = originalCustomFormat;
                isNull = false;
            }
        }
        base.OnCloseUp(eventargs);
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);

        // on delete key press, set to min value (null)
        if (e.KeyCode == Keys.Delete)
        {
            this.Value = DateTime.MinValue;
        }
    }
}
KyleMit
  • 30,350
  • 66
  • 462
  • 664
splattne
  • 102,760
  • 52
  • 202
  • 249
  • 1
    Yes Mr Grazoli's NullableDateTimePicker does do the job although I think that someone should review it and try and get rid of those ugly WndProc calls – Calanus Jul 18 '09 at 07:19
  • The other thing about the code is that it didn't seem to do what it was supposed to do. I don't know, maybe I was doing something wrong. Don't have a lot of time to spend messing around with it. Using the DTPs ShowCheckBox idea seems more promising really. – IAbstract Nov 24 '10 at 23:13
  • While the solution allows the user to clear out a date, you can no longer set focus to the control or use the keyboard to re-enter a non null date. One step fwd, two back. – Chad Dec 10 '10 at 15:21
4

Placing an additional checkbox labeled something like "enable notification" that enables / disables the DateTimePicker.

Serhat Ozgel
  • 23,496
  • 29
  • 102
  • 138
2

Tri's solution did not quite cut it for me and so thought Mr. Grazioli and he did something about it: http://www.codeguru.com/csharp/csharp/cs_controls/custom/article.php/c9645

1

Set the ShowCheckBox property to true.

Then you can use the Checked property as follows:

private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
    DateTimePicker thisDateTimePicker = (DateTimePicker)sender;
    if (thisDateTimePicker.Checked == false)
    {
        thisDateTimePicker.CustomFormat = @" "; //space
        thisDateTimePicker.Format = DateTimePickerFormat.Custom;
    }
    else
    {
        thisDateTimePicker.Format = DateTimePickerFormat.Short;
    }
}
KyleMit
  • 30,350
  • 66
  • 462
  • 664
Eduard
  • 21
  • 2
0

I posted my long way around solution, which has some findings in the code comments about the peculiar issues with this control:

DateTime Picker null value

quickdraw
  • 101
  • 8