Reputation: 891
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;
}
}
}
}
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
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
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
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
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
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
Reputation: 55039
DateTimePicker
s 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