17
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

4

6 回答 6

27

DateTimePickers 不能设置为 null,因为DateTime不能为 null,但您可以将它们设置DateTime.MinValue为 uninitialized 的默认值DateTime。然后您只需检查是否存在dtp.Value = DateTime.MinValue,如果是,则将其视为空值。

但是,如果要真正区分什么时候没有选择值,最简单的方法是设置DateTimePicker.ShowCheckBox为true,然后检查dtp.Checked,如果为true,则读取该值,否则将其视为null。

于 2010-06-06T09:42:51.297 回答
17

您可以检查您的绑定源是否提供了“空日期”或您不想显示的日期值。

如果是这样,请选择自定义格式:

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

添加“CloseUp”或“ValueChanged”事件处理程序以重置用户操作的格式:

yourDTP.Format = DateTimePickerFormat.Short
于 2013-03-15T10:36:08.323 回答
2

这就是我解决它的方法。我不能有 NULLS,所以我将 1/1/1980 12am 定义为 MYNULLDATE。我在 datetimepicker 的文本和值上使用了数据绑定。我没有使用 datetimepicker 中的复选框。我没有将格式从短格式转换为自定义格式。它似乎触发了 valuechanged 事件,所以我只使用了 custom 并更改了 customformat。我使用了一个流程面板和一个非绑定复选框来坐在日期时间选择器的前面。

代码示例

   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;
            }
        }

    }

在非绑定复选框中

  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);
        }
    }
于 2014-02-25T21:23:50.847 回答
2

我喜欢 ShowCheckBox 选项。我会更进一步,并使用两种扩展方法对其进行封装,以避免重复并具有更清晰的代码:

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;
}

然后,get 和 set 代码如下所示:

dtpSafetyApprover.NullableValue(model.SafetyApproverDate); // set
model.SafetyApproverDate = dtpSafetyApprover.NullableValue(); // get
于 2013-07-11T19:52:01.033 回答
2

最简单的方法是添加一个文本框并将可见属性设置为 false。在日期选择器的 valuechanged 事件上,使用选择器控件的相同日期时间值填充文本框。如果 null 字符串将值设置为 null,请检查文本框的值。

于 2013-09-24T00:01:31.493 回答
0

使用 Vs 2015 并且没有运气绑定 DateTimePicker 控件。最简单的事情似乎只是不绑定它 - 手动将对象的值传递给控件并从控件传递给对象。几行代码将为您省去很多麻烦...

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;
    }
}
于 2016-07-23T18:01:03.593 回答