Windows Develop Bookmark and Share   
 index > Windows Forms Data Controls and Databinding > DataGridView CalendarColumn example doesn't handle keyboard input
 

DataGridView CalendarColumn example doesn't handle keyboard input

Hey all-

I have a DataGridView in which I wanted to host a DateTimePicker, so I used the example from:

http://msdn2.microsoft.com/en-us/library/7tas5c80.aspx

Has anyone gotten this example working properly for keyboard input? It works great when you use the mouse, but under certain circumstances the value from the editing control doesn't get back into the datagridview.

To reproduce:

  1. Enter the date cell with the mouse
  2. Type a new month with thenumeric keys only
  3. Hit Tab or enter toleave the cell.

Now, the above works fine if you leave the editing control with the mouse, or if you use theup/down arrow keys to change the month value.

I did some debugging in the editing control, and it appears that if the follow the steps about the EditingControlFormattedValue property is not being called after the OnValueChanged function fires. Normally that property is being retrieved prior to the EndEdit event on the datagridview.

Does anyone have any ideas on what to check?

Thanks,

Korey

Korey Atterberry  Monday, October 09, 2006 7:09 PM

Ok, if anyone else finds themselves in the same situation, I found a fix. Add the CellLeave event handler to your datagridview and use the following code:

void dgv_CellLeave(object sender, DataGridViewCellEventArgs e)

{

if (dgv.EditingControl is CalendarEditingControl)

{

dgv.EditingPanel.Select(); // force validation on editing control

}

}

Korey Atterberry  Tuesday, October 17, 2006 5:43 PM

I did some more research on this issue, and while I don't have a solution I'm got some more information:

Here's what happens when you tab into a calendar cell, hit f2 to edit, hit the up arrow key, then hit tab to leave the cell:

  1. dgv::CellBeginEdit
  2. CalendarEditingControl::OnValueChanged:10/11/2006 12:00:00 AM
  3. CalendarEditingControl::InitializeEditingControl:10/11/2006 12:00:00 AM
  4. dgv::EditingControlShowing
  5. CalendarEditingControl::GetEditingControlFormattedValue:10/11/2006
  6. CalendarEditingControl::EditingControlWantsInputKey: up arrow
  7. CalendarEditingControl::OnValueChanged:11/11/2006 12:00:00 AM
  8. CalendarEditingControl::GetEditingControlFormattedValue:11/11/2006
  9. dgv::CellValidating
  10. CalendarEditingControl::GetEditingControlFormattedValue:11/11/2006
  11. dgv::CellValidated
  12. dgv::CellEndEdit

Now here's what happens when you tab into a calendar cell, hit f2 to edit, type a number, then hit tab to leave the cell:

  1. dgv::CellBeginEdit
  2. CalendarEditingControl::OnValueChanged:10/11/2006 12:00:00 AM
  3. CalendarEditingControl::InitializeEditingControl:10/11/2006 12:00:00 AM
  4. dgv::EditingControlShowing
  5. CalendarEditingControl::GetEditingControlFormattedValue:10/11/2006
  6. CalendarEditingControl::EditingControlWantsInputKey: numeric 7
  7. CalendarEditingControl::GetEditingControlFormattedValue:10/11/2006
  8. dgv::CellValidating
  9. dgv::CellValidated
  10. CalendarEditingControl::OnValueChanged:7/11/2006 12:00:00 AM
  11. dgv::CellEndEdit

Notice that the OnValueChanged handler with the new date (7/11/2006) doesn't get called until after the cell validation, etc. on the datagridview... If I understand correctly, the datagridview's cell is being flagged as dirty in that OnValueChanged function on the CalendarEditingControl. The editing control is never being asked for its new value (through GetEditingControlFormattedValue).

By the way, I also added the numeric keys to the WantsInputKey override on the CalendarEditingControl, but that didn't change anything.

Anyone have any ideas?

Thanks,

Korey

Korey Atterberry  Wednesday, October 11, 2006 3:16 PM

In the CalendarEditiingControl class there is a function EditingControlWantsInputKey. It is only allowing the left, up, down, right, home, end, pageup, and pagedown keys to go to the DateTimePicker. You can add to the list of the accepted keys.



Class CalendarEditingControl
Inherits DateTimePicker
Implements IDataGridViewEditingControl
etc...........
Public Function EditingControlWantsInputKey(ByVal key As Keys, _
ByVal dataGridViewWantsInputKey As Boolean) As Boolean _
Implements IDataGridViewEditingControl.EditingControlWantsInputKey
' Let the DateTimePicker handle the keys listed.
Select Case key And Keys.KeyCode
Case Keys.Left, Keys.Up, Keys.Down, Keys.Right, _
Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp
Return True
Case Else
Return False
End Select
End Function


Ken Tucker  Wednesday, October 11, 2006 4:06 PM

Thanks for the reply, Ken. However, I've already tried that. Ireturned true forD0, D1, D2, etc. I traced the execution,and WantsInputKey gets called and does in fact return true when I type a numeric key. It didn't change the order of execution I listed above, unfortunately... It really seems like that should be the right answer.

Thanks,

Korey

Korey Atterberry  Wednesday, October 11, 2006 10:48 PM

I have one more piece of information I just found. Like I said before, if you enter the cell, type one number, then tab out, the cell loses its value. What I discovered is that if you type TWO number (i.e. "12" or "04"), then tab out, the cell keeps its value. Also, hitting a number then Left, Right, Up, Down, plus, minus, etc. also keeps the value.

I guess I've found a workaround... but I don't think my users will buy that one!

Korey

Korey Atterberry  Thursday, October 12, 2006 12:31 AM

Ok, if anyone else finds themselves in the same situation, I found a fix. Add the CellLeave event handler to your datagridview and use the following code:

void dgv_CellLeave(object sender, DataGridViewCellEventArgs e)

{

if (dgv.EditingControl is CalendarEditingControl)

{

dgv.EditingPanel.Select(); // force validation on editing control

}

}

Korey Atterberry  Tuesday, October 17, 2006 5:43 PM

This workaround creates a new problem:

If you try to click away from the DataGridView while this Editing Control is showing, the program will freeze for a reason I have yet been unable to determine.

ALight  Monday, February 12, 2007 8:41 AM
I've just encountered this problem too. Have you found a workaround that doesn't cause any other problems?

Chris Gin  Monday, May 21, 2007 12:00 AM
Also I have another question. How do you enable the user to blank out a value once a date has been selected? Ideally I would like them to be able to select the entire date and hit Backspace or Delete like a normal text field.

Chris Gin  Monday, May 21, 2007 12:09 AM

Here are answers to both of your questions:

Chris Gin wrote:
I've just encountered this problem too. Have you found a workaround that doesn't cause any other problems?

My workaround was to place the following code into the DGV [CellValidating] event (not the CellLeave event):

Code Snippet

'This code is required in case the user keys in only one digit, then presses Tab; otherwise, the

' control (and therefore the cell) will not accept the new value. Simply set the first variable (DGV)

' to the DataGridView to which the DTPColumn Type is in.

Dim DGV As DataGridView = Me.LE_DGV

Dim ColumnTypeToWhichEPSelectIsApplied As Type = GetType(DTPColumn) 'Column Type To Which EditingPanel.Select Is Applied

If (DGV.Columns(e.ColumnIndex).GetType Is ColumnTypeToWhichEPSelectIsApplied) Then

If DGV.EditingPanel IsNot Nothing Then

DGV.EditingPanel.Select()

End If

End If

'******End DTPColumn Workaround******

Chris Gin wrote:
Also I have another question. How do you enable the user to blank out a value once a date has been selected? Ideally I would like them to be able to select the entire date and hit Backspace or Delete like a normal text field.

In order to clear the value, you should handle the DGV [KeyDown] event for individual columns, like so:

Code Snippet

'Keys.Delete will set the underlying value to null (for certain cells)

Dim CurCell As DataGridViewCell = Me.LE_DGV.CurrentCell

If CurCell IsNot Nothing Then

If (CurCell.OwningColumn Is [Insert Columns to which you want to apply the "Clear Date" functionality]) _

Or (CurCell.OwningColumn Is Me.LE_colTE) _

Or (CurCell.OwningColumn Is Me.LE_colEH) Then

If e.KeyCode = Keys.Delete Then 'Here, you could also check for e.KeyCode= Keys.Back (so user can press either Del or Backspace to clear the value)

'Set the DateTime value to null

CurCell.Value = DBNull.Value

End If

End If

End If

Hope that helps you.

Andre

ALight  Monday, May 21, 2007 5:03 AM
Thanks Andre. The workaround worked a treat.
Chris Gin  Wednesday, May 30, 2007 10:22 PM

Has anyone tried using the Calendar Column with a nullable DateTimePicker ? I can't get it to work ...


Thanks.

chieripot  Wednesday, June 20, 2007 3:13 PM

You can use google to search for other answers

Custom Search

More Threads

• Expression column VS2005 bug
• Populating VB.Net Listview from Access Database
• Spontaneous column rearrangement
• VB.net
• Applying paging to DataGridView
• combobox help
• can't set the value of comboBox.selectedValue
• Delete + DataGridView + CurrentItemChanged
• DataGridView wont show new entry..until i run it again
• Progressive search using ComboBox