none
DataGridView CalendarColumn example doesn't handle keyboard input RRS feed

  • Question

  •  

    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 the numeric keys only
    3. Hit Tab or enter to leave the cell.

    Now, the above works fine if you leave the editing control with the mouse, or if you use the up/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

    Monday, October 9, 2006 7:09 PM

Answers

  • 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

      }

    }

    Tuesday, October 17, 2006 5:43 PM

All replies

  • 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

     

    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


     

    Wednesday, October 11, 2006 4:06 PM
  • Thanks for the reply, Ken.  However, I've already tried that.  I returned true for D0, 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

     

    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

    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

      }

    }

    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.

    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?

    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.

    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

     

     

    Monday, May 21, 2007 5:03 AM
  • Thanks Andre. The workaround worked a treat.
    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.

    Wednesday, June 20, 2007 3:13 PM
  • That is not a big issue.

    You have to Edit the CalenderEditingControl. Replace the EditingControlFormattedValue to the given below code. Or else you just have to remove the get return with return this.value.Tostring(); it will remain the same date and time in the cell. I hope the answer the Question.

     

     

     

    public object EditingControlFormattedValue

    {

     

     

    get

    {

     

     

    return this.Value.ToString();

    }

     

     

    set

    {

     

     

    if (value is String)

    {

     

     

    this.Value = DateTime.Parse((String)value);

    }

    }

    }

    Have Any Question Reply me Back

    Saturday, January 8, 2011 8:34 PM
  • Get me with your perfect Question. I am here to Answer...
    Saturday, January 8, 2011 8:35 PM
  • Thanks! This helped me a great time.
    Monday, February 17, 2014 10:01 AM