Introduction
I have always known a lot of people who have problems with the standard .NET 2.0 DataGridView
and the nullable DateTime
column (created with Oracle PL/SQL column definition):
dtReceived DATE
or a MS SQL Server DateTime
column with NULL values in Transact SQL:
dtReceived DATETIME NULL
Google Search normally gives this Microsoft sample for calendar columns: How to: Host Controls in Windows Forms DataGridView Cells. This is a good start point, but it isn't enough. You can never correctly fill DateTime DataGridView
cells with NULL
. I found many variants for the simple DateTimePicker
class, but work samples absent for nullable DateTime
columns in a DataGridView
.
Solution
I spent a lot of time on the Internet searching, and found a nice article about a nullable DateTimePicker
: DateTimePicker DBNull. I then made several corrections and as 'magic touch', and it works for DataGridView
s now.
Using the code
These are the steps we need:
- Rename the class
DateTimePicker
to DatePicker
(the same name for different classes is a bad practice, in my opinion):
public class DatePicker : System.Windows.Forms.DateTimePicker
{..
- Add the following code snippet to the
DatePicker
class:
public string ToShortDateString()
{
if (!realDate)
return String.Empty;
else
{
DateTime dt = (DateTime)Value;
return dt.ToShortDateString();
}
}
- Correct CalendarEditingControl.cs from the Microsoft Sample for usage in our
DatePicker
:
class CalendarEditingControl : DatePicker, IDataGridViewEditingControl { ...
- Correct CalendarCell.cs from the Microsoft Sample for
DBNull
:
public override void InitializeEditingControl(int rowIndex, object
initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue,
dataGridViewCellStyle);
CalendarEditingControl ctl =
DataGridView.EditingControl as CalendarEditingControl;
object val = null;
try
{
val = this.Value;
}
catch (Exception ex)
{
return;
}
if (val != System.DBNull.Value)
ctl.Value = (DateTime)val;
}
That's all, folks :)
You should press the DEL key to set a NULL
filled DateTime
cell.
The source code is attached. You can directly use the files from my project in your projects like in the Microsoft Samples (DatePicker.cs, CalendarCell.cs, CalendarColumn.cs, CalendarEditingControl.cs):
private void Form1_Load(object sender, EventArgs e)
{
CalendarColumn col = new CalendarColumn();
this.dataGridView1.Columns.Add(col);
this.dataGridView1.RowCount = 5;
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
row.Cells[0].Value = DateTime.Now;
}
}
or from the Microsoft Visual Studio Data Designer for DataGrid (right mouse click on DataGridView, and choose 'Edit columns' from the context menu):
I have attached a real sample with database (Visual Studio 2008 / SQL Express database).
History
- 14-Aug-2009: Initial version posted.
- 16-Aug-2009: Database sample added.