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;
}
}
}
}
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
DateTimePicker
s ne peut pas être défini sur null car DateTime
ne peut pas être null, mais vous pouvez les définir sur DateTime.MinValue
, qui est la valeur par défaut pour une DateTime
non initialisée. Et ensuite, il vous suffit de vérifier si le dtp.Value = DateTime.MinValue
et, dans l’affirmative, le traitent comme nul.
Cependant, si vous voulez vraiment distinguer lorsqu'aucune valeur n'a été sélectionnée, le moyen le plus simple consiste à définir DateTimePicker.ShowCheckBox
sur true, puis cochez dtp.Checked
et si c'est vrai, vous lisez la valeur, sinon vous la traitez comme étant nulle.
Vous pouvez vérifier si votre source de liaison fournit une "date NULL" ou une valeur de date que vous ne souhaitez pas afficher.
Si tel est le cas, sélectionnez le format personnalisé:
yourDTP.Format = DateTimePickerFormat.Custom
yourDTP.CustomFormat = " "
Ajoutez un gestionnaire d'événements "CloseUp" ou "ValueChanged" pour réinitialiser le format lors de l'action de l'utilisateur:
yourDTP.Format = DateTimePickerFormat.Short
voici comment je l'ai résolu. Je ne pouvais pas avoir NULLS alors j'ai défini le 1/1/1980 12h00 comme MYNULLDATE. J'ai utilisé la liaison de données sur le texte et la valeur du datetimepicker. Je n'ai pas utilisé la case à cocher dans le datetimepicker. Je n'ai pas alterné les formats de court à la coutume. Il a semblé déclencher des événements de valeur, alors je viens d'utiliser custom et de changer le customformat. J'ai utilisé un flux et une case à cocher NONBOUND pour m'asseoir devant le datetimepicker.
Échantillon du 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;
}
}
}
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);
}
}
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;
}
Ensuite, le code get et set ressemble à ceci:
dtpSafetyApprover.NullableValue(model.SafetyApproverDate); // set
model.SafetyApproverDate = dtpSafetyApprover.NullableValue(); // get
Le moyen le plus simple consiste à ajouter une zone de texte et à définir la propriété visible sur false. Lors de l'événement valuechanged du sélecteur de date, renseignez la zone de texte avec la même valeur date-heure du contrôle de sélecteur. Vérifiez la valeur de la zone de texte si une chaîne null définit la valeur sur null.
À l'aide de Vs 2015 et n'ayant pas de chance, liant un contrôle DateTimePicker. La chose la plus simple semble être simplement de ne pas le lier - gérer manuellement la valeur de votre objet au contrôle et du contrôle à votre objet. 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;
}
}