как установить datetimepicker с нулевым значением, если дата не выбрана (c # winforms) - PullRequest
15 голосов
/ 06 июня 2010
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

я нашел хорошее решение здесь

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

еще одно идеальное решение здесь

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

Ответы [ 6 ]

22 голосов
/ 06 июня 2010

DateTimePicker s не может быть установлено на ноль, потому что DateTime не может быть нулевым, но вы можете установить их на DateTime.MinValue, что является значением по умолчанию для неинициализированного DateTime. И тогда вы просто проверяете, является ли dtp.Value = DateTime.MinValue, и если да, рассматриваете его как ноль.

Однако, если вы хотите действительно различать, когда никакое значение не было выбрано, самый простой способ - установить DateTimePicker.ShowCheckBox в true, а затем вы проверяете dtp.Checked, и если оно истинно, вы читаете значение, иначе вы обрабатываете это как ноль.

13 голосов
/ 15 марта 2013

Вы можете проверить, содержит ли источник привязки «нулевую дату» или значение даты, которое вы не хотите отображать.

Если это так, выберите пользовательский формат:

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

Добавьте обработчик событий «CloseUp» или «ValueChanged» для сброса формата при действии пользователя:

yourDTP.Format = DateTimePickerFormat.Short
2 голосов
/ 26 февраля 2014

вот как я это решил. У меня не могло быть NULLS, поэтому я определил 1 января 1980 года как MYNULLDATE. Я использовал привязку данных к тексту и значению datetimepicker. Я не использовал флажок в datetimepicker. Я не чередовал форматы от коротких до пользовательских. Похоже, что он запускает события с измененным значением, поэтому я просто использовал custom и изменил формат custom. Я использовал Flowpanel и NONBOUND флажок, чтобы сидеть перед datetimepicker.

Образец кода

   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);
        }
    }
2 голосов
/ 24 сентября 2013

Самый простой способ - добавить текстовое поле и установить для свойства visible значение false. В случае события valuezed средства выбора даты заполните текстовое поле тем же значением даты и времени элемента управления средства выбора. Проверьте значение текстового поля, если пустая строка устанавливает значение в null.

2 голосов
/ 11 июля 2013

Мне нравится опция 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
0 голосов
/ 23 июля 2016

Использование 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;
    }
}
...