shmandor
shmandor

Reputation: 891

how to set datetimepicker with null value if date not selected(c# winforms)

Binding b = new Binding( "Value", person, "BdayNullable", true );
dtBirthdayNullable.DataBindings.Add( b );
b.Format += new ConvertEventHandler( dtBirthdayNullable_Format );

b.Parse += new ConvertEventHandler( dtBirthdayNullable_Parse );

void dtBirthdayNullable_Format( object sender, ConvertEventArgs e )
{
    // e.Value is the object value, we format it to be what we want to show up in the control

    Binding b = sender as Binding;
    if ( b != null )
    {
        DateTimePicker dtp = (b.Control as DateTimePicker);
        if ( dtp != null )
        {
            if ( e.Value == DBvalue.value )
            {
                dtp.ShowCheckBox = true;
                dtp.Checked = false;

                // have to set e.Value to SOMETHING, since it's coming in as NULL
                // if i set to DateTime.Today, and that's DIFFERENT than the control's current 
                // value, then it triggers a CHANGE to the value, which CHECKS the box (not ok)
                // the trick - set e.Value to whatever value the control currently has.  
                // This does NOT cause a CHANGE, and the checkbox stays OFF.
                e.Value = dtp.Value;    
            }
            else
            {
                dtp.ShowCheckBox = true;
                dtp.Checked = true;
                // leave e.Value unchanged - it's not null, so the DTP is fine with it.
            }
        }
    }
}
void dtBirthdayNullable_Parse( object sender, ConvertEventArgs e )
{
    // e.value is the formatted value coming from the control.  
    // we change it to be the value we want to stuff in the object.

    Binding b = sender as Binding;
    if ( b != null )
    {
        DateTimePicker dtp = (b.Control as DateTimePicker);
        if ( dtp != null )
        {
            if ( dtp.Checked == false )
            {
                dtp.ShowCheckBox = true;
                dtp.Checked = false;
                e.Value = DBvalue.Value
            }
            else
            {
                DateTime val = Convert.ToDateTime( e.Value );
                e.Value =val;
            }
        }
    }
}

EDIT

i found a good solution here

http://blogs.interknowlogy.com/danhanan/archive/2007/01/21/10847.aspx

another perfect solution here

http://www.mofeel.net/70-microsoft-public-dotnet-framework-windowsforms/8806.aspx

Upvotes: 19

Views: 92231

Answers (6)

Steven Bell
Steven Bell

Reputation: 1

Using Vs 2015 and having no luck binding a DateTimePicker control. The easiest thing seems to be simply not binding it- handle passing the value of your object to the control and from the control to your object manually. A few lines of code will save you lots of headaches...

private void BindData()
{
    // can't bind the datetimepicker, so handle it manually...
    if (o.myDate == null)
    {
        dtDatePicker.Checked = false;
    }
    else
    {
        dtDatePicker.Checked = true;
        dtDatePicker.Value = o.myDate.Value;
    }
}

private void Save()
{
    if (dtDatePicker.Checked)
    {
        o.myDate = dtDatePicker.Value;
    }
    else
    {
        o.myDate = null;
    }
}

Upvotes: 0

yolomann
yolomann

Reputation: 21

this is how i solved it. I couldn't have NULLS so I defined 1/1/1980 12am as MYNULLDATE. I used databinding on the text and value of the datetimepicker. I did not use the checkbox in the datetimepicker. I did not alternat formats from short to custom. It appeared to fire valuechanged events so i just used custom and changed the customformat. I used a flowpanel and a NONBOUND checkbox to sit in front of the datetimepicker.

Sample of the code

   private void dateTimePicker_ValueChanged(object sender, EventArgs e)
    {
        if (sender != null && sender.GetType() == typeof(DateTimePicker))
        {
            if (((DateTimePicker)(sender)).Value == MYNULLDATE)
            {
                ((DateTimePicker)(sender)).CustomFormat = " ";
                checkBoxDate.Checked = false;
            }
            else
            {
                ((DateTimePicker)(sender)).CustomFormat = "M/d/yyyy";
                checkBoxDate.Checked = true;
            }
        }

    }

In the Non Bound CheckBox

  private void checkBoxDate_Click(object sender, EventArgs e)
    {
        if (bindingSource != null && bindingSource.Current != null &&
             bindingSource.Current.GetType() == typeof(MyRecord))
        {
            MyRecord a = (MyRecord)bindingSource.Current;
            if (checkBoxDate.Checked == false)
            {
                a.Date = MYNULLDATE;
                dateTimePicker.Enabled = false;
            }
            else
            {
                if (a.Date == null || a.Date == MYNULLDATE)
                {
                    dateTimePicker.Enabled = true;
                    a.Date = DateTime.Now;
                }
            }
            bindingSource.ResetBindings(false);
        }
    }

Upvotes: 2

user2809116
user2809116

Reputation: 21

The easiest way is to add a text box and set the visible property to false. On the valuechanged event of the date picker populate the text box with the same date time value of the picker control. Check the value of the text box if null string set the value to null.

Upvotes: 2

James R.
James R.

Reputation: 840

I like the ShowCheckBox option. I would take it one step further and encapsulate it with two extension methods to avoid duplication and have cleaner looking code:

public static DateTime? NullableValue(this DateTimePicker dtp)
{
    return dtp.Checked ? dtp.Value : (DateTime?)null;
}

public static void NullableValue(this DateTimePicker dtp, DateTime? value)
{
    dtp.Checked = value.HasValue;
    if (value.HasValue) dtp.Value = value.Value;
}

Then, the get and set code looks like:

dtpSafetyApprover.NullableValue(model.SafetyApproverDate); // set
model.SafetyApproverDate = dtpSafetyApprover.NullableValue(); // get

Upvotes: 2

AvS
AvS

Reputation: 191

You can check if your binding source delivers a "null date" or a date value that you don't want to display.

If so, select custom format:

yourDTP.Format = DateTimePickerFormat.Custom
yourDTP.CustomFormat = " "

Add a "CloseUp" or "ValueChanged" event handler to reset the format on user action:

yourDTP.Format = DateTimePickerFormat.Short

Upvotes: 19

Hans Olsson
Hans Olsson

Reputation: 55039

DateTimePickers can't be set to null because DateTime can't be null, but you can set them to DateTime.MinValue which is the default value for an uninitialized DateTime. And then you just check if the dtp.Value = DateTime.MinValue and if so, treat it as null.

However, if you want to really distinguish when no value has been selected, the easiest way is to set DateTimePicker.ShowCheckBox to true, and then you check dtp.Checked and if it's true, you read the value, otherwise you treat it as a null.

Upvotes: 28

Related Questions