我正在修改一些具有自定义日历控件的代码,其中使用 DataGridView
的 DateTimePicker
。我已经设置了 ShowCheckBox = true ,并且当用户单击复选框时,我试图强制它将日期值更改为 null(通过更改日期),有效。我的问题是,需要多次单击复选框才能更改日期格式。我的基本日历列来自 http://msdn.microsoft.com/en-us/library/7tas5c80.aspx ,但不包含复选框并且不允许空值。
我的OnValueChanged()
代码是:
protected override void OnValueChanged(EventArgs eventargs)
{
// Notify the DataGridView that the contents of the cell
// have changed.
base.OnValueChanged(eventargs);
if (this.Checked)
{
this.Checked = true;
this.Format = DateTimePickerFormat.Short;
} else if (!this.Checked)
{
this.Format = DateTimePickerFormat.Custom;
this.CustomFormat = " ";
}
}
第一次单击复选框(当选中其值时)会使日期变灰,但不会触发 OnValueChanged()
方法,第二次单击将其设置回“已选中”,并且触发该事件,第三次单击将 CustomFormat
设置为“”,因此按其应有的方式显示空日期。
我做了一些研究,我认为我的问题与第一次点击时获得单元格焦点有关,但如果我将检查放在 onGotFocus()
中,单击将显示/隐藏日期格式,但当我取消选中复选框后单击另一个单元格时,它仍然将 CustomFormat
设置为“”而不是 DateTimePickerFormat。简短
。
类似主题的其他答案请参阅http://www.mofeel.net/70-microsoft-public-dotnet-framework-windowsforms/8806.aspx ,但我对如何将其合并到我的代码中感到困惑。我还没有发布整个类(class),但如果有人认为这会有帮助,可以做吗?
最佳答案
一位同事帮我解决了这个问题。我会尽力解释:
我的 OnValueChanged()
方法最终看起来像:
protected override void OnValueChanged(EventArgs eventargs)
{
valueChanged = true;
// Notify the DataGridView that the contents of the cell
// have changed.
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.OnValueChanged(eventargs);
isChecked();
}
public bool isChecked()
{
bool isChecked = false;
if (this.Checked)
{
this.Checked = true;
this.Format = DateTimePickerFormat.Short;
isChecked = true;
}
else if (!this.Checked)
{
this.Format = DateTimePickerFormat.Custom;
this.CustomFormat = " ";
isChecked = false;
}
return isChecked;
}
他还添加了这些方法:
protected override void OnClick(EventArgs e)
{
isChecked();
base.OnClick(e);
}
public object EditingControlFormattedValue
{
get
{
if (!this.Checked)
{
return String.Empty;
}
else
{
if (this.Format == DateTimePickerFormat.Custom)
{
return this.Value.ToString();
}
else
{
return this.Value.ToShortDateString();
}
}
}
set
{
string newValue = value as string;
if (!String.IsNullOrEmpty(newValue))
{
this.Value = DateTime.Parse(newValue);
}
}
}
InitializaEditingControl
也被编辑为:
public override void InitializeEditingControl(int rowIndex, object
initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
// Set the value of the editing control to the current cell value.
base.InitializeEditingControl(rowIndex, initialFormattedValue,
dataGridViewCellStyle);
ctl = DataGridView.EditingControl as CalendarEditingControl;
// ctl.Invalidated += new InvalidateEventHandler(ctl_Invalidated);
ctl.ValueChangedSpecial += new EventHandler(ctl_ValueChangedSpecial);
if (rowIndex >= 0)
{
try
{
if (String.IsNullOrEmpty(this.Value.ToString()))
{
ctl.Checked = false;
ctl.Format = DateTimePickerFormat.Custom;
ctl.CustomFormat = " ";
}
else
{
ctl.Checked = true;
ctl.Value = (DateTime)this.Value;
ctl.Format = DateTimePickerFormat.Short;
}
}
catch (ArgumentOutOfRangeException aex)
{
//MessageBox.Show("ERROR. " + aex.Message);
ctl.Value = (DateTime)this.DefaultNewRowValue;
}
}
}
然后就成功了。
这个答案几乎肯定不能令人满意,但未回答的问题对任何人都没有帮助,所以希望这里的一些东西可以帮助其他人。
关于c# - DateTimePicker 需要多次单击复选框才能触发 OnValueChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19313741/