comment définir datetimepicker avec une valeur nulle si la date n'est pas sélectionnée(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
j'ai trouvé une bonne solution ici
http://blogs.interknowlogy.com/danhanan/archive/2007/01/21/10847.aspx
une autre solution parfaite ici
http://www.mofeel.net/70-microsoft-public-dotnet-framework-windowsforms/8806.aspx
6 réponses
DateTimePicker
s ne peut pas être défini à null parce que DateTime
ne peut pas être nulle, mais vous pouvez les configurer pour DateTime.MinValue
qui est la valeur par défaut pour un non initialisée DateTime
. Et ensuite vous vérifiez juste si le dtp.Value = DateTime.MinValue
et si, le traiter comme nulle.
Toutefois, si vous voulez vraiment distinguer lorsque aucune valeur n'a été sélectionné, le plus simple est de définir DateTimePicker.ShowCheckBox
true, puis vous cochez dtp.Checked
et si c'est vrai, vous lisez la valeur, sinon vous le traiter comme un null.
vous pouvez vérifier si votre source de liaison fournit une "date nulle" ou une valeur de date que vous ne voulez pas afficher.
si oui, sélectionnez custom format:
yourDTP.Format = DateTimePickerFormat.Custom
yourDTP.CustomFormat = " "
Ajouter un gestionnaire d'événements" CloseUp "ou" ValueChanged " pour réinitialiser le format sur l'action de l'utilisateur:
yourDTP.Format = DateTimePickerFormat.Short
j'aime L'option ShowCheckBox. Je voudrais aller un peu plus loin et l'encapsuler avec deux méthodes d'extension pour éviter la duplication et avoir un code plus propre:
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;
}
alors, le code get and set ressemble à:
dtpSafetyApprover.NullableValue(model.SafetyApproverDate); // set
model.SafetyApproverDate = dtpSafetyApprover.NullableValue(); // get
Le plus simple est d'ajouter une zone de texte et définissez la propriété visible à false. Sur l'événement valuechanged de la date picker remplir la zone de texte avec la même date valeur de temps de la commande picker. Cochez la valeur de la zone de texte si la chaîne de caractères null définit la valeur à null.
c'est comment je l'ai résolu. Je ne pouvais pas avoir NULLS donc j'ai défini 1/1/1980 12am comme MYNULLDATE. J'ai utilisé la datation sur le texte et la valeur du datetimepicker. Je n'ai pas coché la case dans le datetimepicker. Je n'ai pas alterné les formats courts et personnalisés. Il est apparu pour le feu valuechanged events donc j'ai juste utilisé personnalisé et changé le formulaire personnalisé. J'ai utilisé un débitmètre et une case à cocher pour m'asseoir devant le 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;
}
}
}
dans la case à cocher non liée
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);
}
}
utiliser Vs 2015 et n'avoir aucune chance de lier un contrôle DateTimePicker. La chose la plus simple semble être de ne pas le lier - poignée passant la valeur de votre objet au contrôle et du contrôle à votre objet manuellement. Quelques lignes de code vous éviteront beaucoup de maux de tête...
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;
}
}