0
votes

I have a C# WinForms project targeting .NET 3.5 with two DataGridViews. Visual Studio 2010 Pro on Win 7 64 bit.

I'm using two DateTimePicker controls (one for time and one for date) created at run-time which are floating on top of the appropriate DateTime cells in the gridview. The pickers are only displayed when a time or date cell gets focus.

System time format is 24 hours.

private DateTimePicker timePicker;

timePicker = new DateTimePicker();
timePicker.Format = DateTimePickerFormat.Custom;
timePicker.CustomFormat = "HH:mm";
timePicker.MaxDate = new DateTime(9998, 12, 31);
timePicker.MinDate = new DateTime(1753, 01, 01);
timePicker.ShowUpDown = true;
timePicker.Width = 60;
timePicker.Hide();
timePicker.ValueChanged += new EventHandler(timePicker_ValueChanged);
timePicker.KeyPress += new KeyPressEventHandler(timePicker_KeyPress);
timePicker.LostFocus += new EventHandler(timePicker_LostFocus);
dgTxSummary.Controls.Add(timePicker);

void timePicker_ValueChanged(object sender, EventArgs e)
{
   // dgTxSummary is the DataGridView containing the dates and times
   dgTxSummary.CurrentCell.Value = timePicker.Value;            
}

void timePicker_LostFocus(object sender, EventArgs e)
{
   timePicker.Hide();
}

// Used for debugging; shows a message in a text field when 10, 20 etc
// where entered
void timePicker_KeyPress(object sender, KeyPressEventArgs e)
{
   if (Char.IsDigit(prevChar) && e.KeyChar == '0')
   {
      string correctHour = prevChar.ToString() + '0';
      Message = "Should have been " + correctHour;
   }

   prevChar = e.KeyChar;
}

When a time cell is clicked, the timepicker is displayed

private void ShowTimePicker(Point cellPos, DateTime dt)
{
  timePicker.Location = cellPos;
  timePicker.Value = dt;
  timePicker.Show();
  timePicker.Focus();
}

The problem only occurs when 2 conditions are met:

1) the first time a number is entered after the picker gets focus
2) a valid number ending with 0* is manually entered (keyboard)

*0, 10 or 20 in the hour slot, 0, 10, ... , 50 in the minute slot

Using the updown buttons works fine.

The result is that at first the previous time or date is shown and the updown buttons disappear the control (timepicker) is either hidden or closed, and the underlying cell in the datagridview has focus and is in edit mode with the previous time or date. When clicking inside or outside the cell, 01 is shown if 10 was entered.

I've created a design-time datetimepicker on the same form, and it works normally.

What am I missing?

1
Post code for these methods too: timePicker_ValueChanged timePicker_KeyPress timePicker_LostFocusFaraday
The datagridview works best with control that implement the IDataGridViewEditingControl interface and a column encapsulating that control. If you want I have a custom date time picker control (mask like textbox with dropdown option for the combobox) that I can post here if you're interested.Me.Name
I'm interested in checking out your suggestion, so I'd appreciate if you could post the code :-) I'd still like to know why my code doesn't work, so any suggestions is most welcomeuser1437420

1 Answers

0
votes

I've finally found the culprit in the code:

dgTxSummary.Controls.Add(timePicker);

It seems the DateTimePicker needs to be added to the form, not the DataGridView.

After changing the code to this.Controls.Add(timePicker); and using datePicker.BringToFront(); in ShowTimePicker(...) (to avoid the control being hidden behind the DataGridView), all is good :-)

FWIW I use the following code to place the DateTimePicker on top of the corresponding cell (code stripped of error handling, null checking etc):

private void dgTxSummary_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    Rectangle cellRect = dgTxSummary.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false);
    Point dgPos = dgTxSummary.Location;
    Point cellPos = new Point(dgPos.X + cellRect.X, dgPos.Y + cellRect.Y);

    DateTime dt = DateTime.Parse(row.Cells[e.ColumnIndex].FormattedValue.ToString());

    ShowDatePicker(cellPos, dt);
}