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;
}
}
}
}
ここで良い解決策を見つけました
http://blogs.interknowlogy.com/danhanan/archive/2007/01/21/10847.aspx
ここで別の完璧なソリューション
http://www.mofeel.net/70-Microsoft-public-dotnet-framework-windowsforms/8806.aspx
DateTimePicker
はnullにできないため、DateTime
sをnullに設定することはできませんが、初期化されていないDateTime
のデフォルト値である_DateTime.MinValue
_に設定できます。そして、_dtp.Value = DateTime.MinValue
_かどうかを確認し、そうであればそれをnullとして扱います。
ただし、値が選択されていないときに本当に区別したい場合、最も簡単な方法は_DateTimePicker.ShowCheckBox
_をtrueに設定し、次に_dtp.Checked
_をチェックして、それがtrueの場合は値を読み取り、それ以外の場合はnullとして扱います。
バインディングソースが「nullの日付」または表示したくない日付値を提供しているかどうかを確認できます。
その場合は、カスタム形式を選択します。
yourDTP.Format = DateTimePickerFormat.Custom
yourDTP.CustomFormat = " "
「CloseUp」または「ValueChanged」イベントハンドラーを追加して、ユーザーアクションの形式をリセットします。
yourDTP.Format = DateTimePickerFormat.Short
これは私がそれを解決した方法です。 NULLを設定できなかったため、1980年1月1日の午前12時をMYNULLDATEとして定義しました。 datetimepickerのテキストと値にデータバインディングを使用しました。 datetimepickerのチェックボックスは使用しませんでした。私は短い形式からカスタム形式にフォーマットを変えませんでした。 valuechangedイベントを起動するように見えたので、カスタムを使用してカスタムフォーマットを変更しました。フローパネルと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);
}
}
ShowCheckBoxオプションが好きです。私はそれをさらに一歩進め、重複を回避し、見栄えのよいコードにするために、2つの拡張メソッドでカプセル化します。
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
最も簡単な方法は、テキストボックスを追加し、visibleプロパティをfalseに設定することです。日付ピッカーのvaluechangedイベントで、ピッカーコントロールの同じ日時値をテキストボックスに入力します。 null文字列がnullに値を設定した場合、テキストボックスの値を確認します。
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;
}
}