none
DataGridView KeyDown?

    Question

  • (VS2005 - beta 2)

    Hello, is there anyway to capture a keypress or keydown event in the DataGridView?  I know there's events called KeyDown and Keypress, but if the DGV is in edit mode, they never get caught. 

    My ultimate goal is to make it so pressing enter moves to the Cell to the right, instead of to the next row but I need to know what key is being pressed before I can do that.

    Thanks
    -Adam
    Wednesday, September 14, 2005 10:49 PM

Answers

  • To handle the KeyDown and KeyPress events for the editing control just handle the EditingControlShowing event and access the events on the editing control. Check out the DataGridView faq for more info: http://www.windowsforms.net/Samples/Go%20To%20Market/DataGridView/DataGridView%20FAQ.doc

    That said, you do have to derive from the DataGridView to do what you want. This is due to the way that keyboard handling works for contained controls. In a future version of the DataGridView we would like to add a few more events (yeah!) to help make this scenario easier to do.
     
    Here is the code you need to make the Enter key move the focus to the right:


    public class dgv : DataGridView
    {
        protected override bool ProcessDialogKey(Keys keyData)
        {
            Keys key = (keyData & Keys.KeyCode);
            if (key == Keys.Enter)
            {
                return this.ProcessRightKey(keyData);
            }
            return base.ProcessDialogKey(keyData);
        }
        protected override bool ProcessDataGridViewKey(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                return this.ProcessRightKey(e.KeyData);
            }
            return base.ProcessDataGridViewKey(e);
        }
    }

     


    -mark

    DataGridView Program Manager

    Microsoft

    This post is provided “as-is”

    Monday, December 05, 2005 6:14 AM

All replies

  • I do want to know the keypress/keydown event for datagrid or view. Any Help please. Thanks. Jil
    Thursday, September 15, 2005 5:37 AM
  • Ive the same problem. Its ridiculous that such improved control cant do that simple thing. Ive tried a lot of ways such Overriden ProcessCMDKeys and nothing. Also ive been searching for help in a lot of forums and nothing.

    It would be great if someone could tell if theres anyway of do that.
    Sunday, December 04, 2005 8:12 PM
  • To handle the KeyDown and KeyPress events for the editing control just handle the EditingControlShowing event and access the events on the editing control. Check out the DataGridView faq for more info: http://www.windowsforms.net/Samples/Go%20To%20Market/DataGridView/DataGridView%20FAQ.doc

    That said, you do have to derive from the DataGridView to do what you want. This is due to the way that keyboard handling works for contained controls. In a future version of the DataGridView we would like to add a few more events (yeah!) to help make this scenario easier to do.
     
    Here is the code you need to make the Enter key move the focus to the right:


    public class dgv : DataGridView
    {
        protected override bool ProcessDialogKey(Keys keyData)
        {
            Keys key = (keyData & Keys.KeyCode);
            if (key == Keys.Enter)
            {
                return this.ProcessRightKey(keyData);
            }
            return base.ProcessDialogKey(keyData);
        }
        protected override bool ProcessDataGridViewKey(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                return this.ProcessRightKey(e.KeyData);
            }
            return base.ProcessDataGridViewKey(e);
        }
    }

     


    -mark

    DataGridView Program Manager

    Microsoft

    This post is provided “as-is”

    Monday, December 05, 2005 6:14 AM
  • Thank you very much Mark. It works great!.

    As i said its not normal for a user that has to fill a lot of fields to have the enter key with that default behavior. Its not a big thing but theres nothing published on the web about this matter. thank you again.
    Tuesday, December 06, 2005 2:24 AM
  • I'll get the docs and DataGridView FAQ updated with this.

     

    -mark

    DataGridView Program Manager
    Microsoft
    This post is provided "as-is"

     

    Tuesday, December 06, 2005 5:30 PM
  • This modified version also adds a new row automatically and hops back to the first column after an enter given in the last column a row higher:



    public class DataGridViewEnter : DataGridView
     {
            protected override bool ProcessDialogKey(Keys keyData)
            {
                Keys key = (keyData & Keys.KeyCode);
                if (key == Keys.Enter)
                {
                    return this.ProcessRightKey(keyData);
                }
                return base.ProcessDialogKey(keyData);
            }

           public new bool ProcessRightKey(Keys keyData)
            {
                Keys key = (keyData & Keys.KeyCode);
                if (key == Keys.Enter)
                {
                    if ((base.CurrentCell.ColumnIndex == (base.ColumnCount - 1)) && (base.CurrentCell.RowIndex == (base.RowCount - 1)))
                    {
                        ((BindingSource)base.DataSource).AddNew();
                        base.CurrentCell = base.Rows[base.RowCount - 1].Cells[0];
                        return true;
                    }

                    if ((base.CurrentCell.ColumnIndex == (base.ColumnCount - 1)) && (base.CurrentCell.RowIndex + 1 != base.NewRowIndex))
                    {
                        base.CurrentCell = base.Rows[base.CurrentCell.RowIndex + 1].Cells[0];
                        return true;
                    }
                    return base.ProcessRightKey(keyData);
                }
                return base.ProcessRightKey(keyData);
            }

            protected override bool ProcessDataGridViewKey(KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Enter)
                {
                    return this.ProcessRightKey(e.KeyData);
                }
                return base.ProcessDataGridViewKey(e);
            }

     



    Hope you guys find it usefull.

    Cheers,

    Paul

    Wednesday, December 07, 2005 1:10 AM
  • This is handy.  But I am having a problem if there is bad data in the last cell of the grid because the DataError event isn't firing when the base.CurrentCell is being changed.  Any ideas on how to fix that?

    Thanks,

    Kevin
    Friday, December 09, 2005 6:43 PM
  • I'm really stuggling with the visual basic documentation on trying to understand how to capture the key events when accessing the editing control of a DataGridView.  Using a standard text column, I want to filter out letters and be able to capture numbers only,  right, left, enter, tab, delete, escape, etc keys to create the behavior I would like.

    Could you please provide exactly how I would use the e.control command to determine the editing control.  I've tried using the calendar example and tried editing for a texbox, to no avlail.

     

    Friday, February 03, 2006 8:30 AM
  • I want to move focus to next cell. I am using DataGridView control for DataEntry. So, When user done with editing particular cell and press enter, focus should go on to the next cell (not next row). How could I do this? please developers help me.. I am looking for this from last 10 days. Not got the solution yet
    Wednesday, February 08, 2006 5:59 AM
  • There is a solution posted by me and others that creates the functionality that you are searching for. Or is it not applicable to you situation?

    Cheers,

    Paul

    Wednesday, February 08, 2006 10:13 AM
  • Adjusted version where the last cell is also being checked...

    public class DataGridViewEnter : DataGridView

    {
    //This override causes the DataGridView to use the enter key in a similar way as
    //the tab key


    protected override bool ProcessDialogKey(Keys keyData)
    {
    Keys key = (keyData & Keys.KeyCode);

    if (key == Keys.Enter)
    {
       return this.ProcessRightKey(keyData);
    }
    return base.ProcessDialogKey(keyData);
    }


    public new bool ProcessRightKey(Keys keyData)
    {
    Keys key = (keyData & Keys.KeyCode);

    if (key == Keys.Enter)
    {
    if ((base.CurrentCell.ColumnIndex == (base.ColumnCount - 1)) && (base.CurrentCell.RowIndex == (base.RowCount - 1)))
    {

    //This causes the last cell to be checked for errors
    base.EndEdit();
    ((BindingSource)base.DataSource).AddNew();
    base.CurrentCell = base.Rows[base.RowCount - 1].Cells[0];
    return true;
    }

    if ((base.CurrentCell.ColumnIndex == (base.ColumnCount - 1)) && (base.CurrentCell.RowIndex + 1 != base.NewRowIndex))
    {
    base.CurrentCell = base.Rows[base.CurrentCell.RowIndex + 1].Cells[0];
    return true;
    }
    return base.ProcessRightKey(keyData);
    }
    return base.ProcessRightKey(keyData);
    }


    protected override bool ProcessDataGridViewKey(KeyEventArgs e)
    {

    if (e.KeyCode == Keys.Enter)
    {
       return this.ProcessRightKey(e.KeyData);
    }
       return base.ProcessDataGridViewKey(e);
    }

    }

     

    Wednesday, February 08, 2006 10:21 AM
  • I'm looking for visual basic programming. There is several postings dealing with C#.  I've tried using some of the C# to visual basic converters but don't seem to get it to work.  I'm not wanting to learn a copmplete new lanquage and well as learn a new editing interface.  Is there a document that can aid Visual Basic users on this new control?  I've tried using the calendar sample and replaced the dateTimePicker with a textbox.  But, the text box is not moved or sized in the DataGridView cell.  So, obviously I'm missing something.  I want to capture any keydown event while the cell is in the editing mode.
    Thursday, February 09, 2006 5:14 AM
  • What happens when a column is not visible? The last code snippet doesn't work. Any ideas?
    Friday, March 31, 2006 1:58 PM
  • Hi Logan

    I would explain step by step

    You have to derive the datagridview class to do this.

    First you have to add a new class1.vb to your project and write some code in it:

    Public Class DGVMod

    'this tells this class that is a datagridview
    Inherits System.Windows.Forms.DataGridView

    'this function do the half of job
    'when you hit a key (like return) it transforms like you
    'have been hit the tab key
    'this doent work when you are editing the cell

    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean

    If keyData = Keys.Return Then
    keyData = Keys.Tab
    With msg
    .WParam = Keys.Tab
    End With
    End If

    Return MyBase.ProcessCmdKey(msg, keyData)
    End Function

    'this second function works when you are editing the cell
    'does the same as the function above changing return for tab
    Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean

    If keyData = Keys.Return Then
    keyData = Keys.Tab
    End If

    Return MyBase.ProcessDialogKey(keyData)
    End Function

    End Class

    Compile your project. You have to drag your new DGVMod control from the toolbox to your form and its done.

    • Proposed as answer by gernotlg Wednesday, April 27, 2011 11:33 AM
    Saturday, May 20, 2006 3:22 AM
  • Hi Mark,

    I have a problem with deletion a row in the DataGridView.

    This is what i need to do. When the user selects the entire row and press on the DELETE key on the keyboard, a messagebox will prompt out to ask for confirmation on deleting this row. If user clicks on Yes, will proceed with the deletion , if clicks on NO, will cancel the action.

    Now what i'm facing is that, whether the user clicks on Yes or No ,deletion process still carries on.

    Can i know what is the problem??Below is my code.

    Private Sub DataGridView1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyDown

    Dim result As MsgBoxResult

    If e.KeyCode = Keys.Delete Then

    result = MessageBox.Show("Are you sure to delete row " & Me.DataGridView1.CurrentCell.RowIndex + 1 & " ? ", "Notice", MessageBoxButtons.YesNo)

    If result = MsgBoxResult.Yes Then

    Me.DataGridView1.Rows.RemoveAt(DataGridView1.CurrentCell.RowIndex)

    ElseIf result = MsgBoxResult.No Then

    e.Handled = False

    Exit Sub

    End If

    End If

    End Sub

    Sunday, May 21, 2006 3:17 AM
  • Hi MacKraken,

    I used the code you provided to derive a DataGridView that will tab to the next cell when ENTER key is being pressed. I faced a problem , when i pressed the ENTER key, it does goes to the next cell but the value i key in previous cell before ENTER key is pressed is not reflected to the Grid, what i mean is that the cell is empty.

    Any idea on that?

     

    Monday, May 29, 2006 10:29 AM
  • Check if the msg  is in the if clause at the proccessCMDKeys function.

    if you write it out the "if" condition, any key you press will be like tab. is it what you meant?. Anyway i reproduced the code i wrote and works fine. Im able to write the cells.

    Wednesday, May 31, 2006 9:20 AM
  • Hi MacKraken,

    can i have your modified code?

    Thanks you.

    Wednesday, May 31, 2006 10:16 AM
  •  

    i didnt modify the code. The code is just the one above. Try to copy and paste.

     

    Wednesday, May 31, 2006 3:55 PM
  • Hi MacKraken,

    using the same code hmmmm. For the build in column type in the datagridview is ok but when i press enter to the next cell on an embedded control to the datagridview. My scenario is like this, i have an embedded customized control the the datagridview. So i lost focus from this cell using the Enter key, the value enter in this cell is nothing for the first time. When i go back to this cell again and try to lost focus using Enter Key there is value in the cell, strange behaviour.....]]

    currently i have a usercontrol
    embedded to the datagrid, i need to double click on the cell then i will be able
    to see the usercontrol. what i want to do is when the user set the focus to the
    cell the usercontrol will display, then when user double clicked on the cell it
    then go into the edit mode of the control. Besides that, when the cell is being
    focused user can press the DELETE key to delete the whole row. When the user is in
    edit mode of the cell pressing the DELETE key will be deleting the value of the cell
    , any idea?

    any idea?

    Thursday, June 01, 2006 12:07 AM
  • what i want to do is when the user set the focus to the
    cell the usercontrol will display

    You have to handle cellenter event with some kind of condition that fires your user control.
    Private Sub DGVMod_CellEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles Me.CellEnter
    'if the cell im moving is combobox then displays an msgbox.
    If
    Me.Columns(Me.CurrentCellAddress.X).CellType.Name = "DataGridViewComboBoxCell" Then
    MsgBox("combobox cell")
    End If
    End Sub

    You can set another type of condition like
    If Me.Columns(Me.CurrentCellAddress.X).Name = "Column2" Then
    'show you user control
    MsgBox("This is the second column")
    End If

    When the user is in edit mode of the cell pressing the DELETE key will be deleting the value of the cell

    if you want to delete the full row when you are editing the cell you have to handle the processCMDKey function like this.

    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean

    Select Case keyData
    'moves to next cell
    Case Keys.Return
    keyData = Keys.Tab
    With msg
    .WParam = Keys.Tab
    End With
    'delete full row
    Case Keys.Delete

    If Me
    .Rows.Count > 1 Then
    Me.EndEdit()
    Me.SetSelectedRowCore(Me.CurrentRow.Index, True)
    Me.Rows.RemoveAt(Me.CurrentRow.Index)
    End If

    End Select 

    Return MyBase.ProcessCmdKey(msg, keyData)
    End Function

     

    Thursday, June 01, 2006 10:13 AM
  • Hi MacKraken,

    I want to delete the row when the cell is being focused.

    In editing mode of the cell, the delete key is just to delete the value in the cell which means deleting the content of the cell not deleting the whole row. any idea?

    thanks you.

    Thursday, June 01, 2006 10:49 AM
  • modify the delete condition as:

    If Me.Rows.Count > 1 And Me.CurrentCell.IsInEditMode = False Then
    Me.EndEdit()
    Me.SetSelectedRowCore(Me.CurrentRow.Index, True)
    Me.Rows.RemoveAt(Me.CurrentRow.Index)
    End If

    Thursday, June 01, 2006 3:56 PM
  • Hi MacKraken,

    thanks for the code, is working.

    Do u have any code on how i can fire my user control?

    thanks you.

     

    Friday, June 02, 2006 5:35 AM
  • Do I have to create my own class. I have the grid just created by moving from the toollbox.

    Is there any possibility to stop moving to the next row by pressing Enter in that case?

    Thanks

    Ela

    Monday, July 31, 2006 1:25 PM
  • You can use keydown event to set

    e.SuppressKeyPress = True

    This way you will get rid of the default behaviour, and on KeyUp you can then assign anything you want as it is shown below:

    If (e.KeyValue = Keys.Enter) Then

    'Do something

    End If

    I hope it helps

     

    Tuesday, August 01, 2006 8:28 AM
  • Lets say that I need to implement my own logic about moving to another cell in dgw, after the user has fisnished editing and pressed enter. Is it possible to have this kind of scenario?

    1) User pressed enter after entering data in a cell
    2) Editing is finished, but the focus still remains on the cell the user is editing
    3) I use event (like CellEndEdit, where I get the ColumnIndex of the cell that the user edited, and move to desired cell

    Most scenarios here handle ProcessDialogKey, and call the ProcessTabKey to move to NEXT cell, but I would like not to move anywhere, but to stay on the current cell (but to get out of the cell edit mode).

    Possible? Ideas?

    Thanx
    Sunday, November 12, 2006 11:37 PM
  • Ok, seems to me that I have found a solution, will test it more. I just need to hear that it is an acceptable way (that it doesnt have any side effects)

    I have managed to find out that when in CellEdit mode, after pressing the CTRL+Enter, focus stays on the current cell, which is what I wanted. So, I have add CTRL in keys

    Protected Overrides Function ProcessDialogKey(KeyData As Keys) As Boolean

        Dim key As keys=keydata and keys.KeyCode

        If key=keys.Enter Then
            keydata=keydata Or keys.Control
        End If

        Return MyBase.ProcessDialogKey(keydata)
    End Function

    And later in CellEndEdit event I move focus to desired cell. Is this approach correct? I mean, adding CTRL doens thave any side affects, or diffent behavior that just presing ENTER?

    Also I am not overrindg ProcessDataGridViewKey, since it si not dealing with edit mode keystrokes. Is this correct?

    One thing more: in one of the posts above, an example is given how to create class that inherits DataGridView class. When I did the same way, I couldnt get any events to fire with the correct declaration of parameters

    for example: e was System.EventsArgs, and not System.Windows.Forms.DataGridViewCellEventArgs, as it should be in CellEndEdit event.

    After I added

    Public Sub New()
        MyBase.New()
    End Sub

    everything was Ok.

    Question: do I need to add Dispose event too, and some other events?
    Monday, November 13, 2006 12:46 AM
  • public new bool ProcessRightKey(Keys keyData)

    {

    Keys key = (keyData & Keys.KeyCode);

    if (key == Keys.Enter)

    {

    if ((base.CurrentCell.ColumnIndex == (base.ColumnCount - 1)) && (base.CurrentCell.RowIndex == (base.RowCount - 1)))

    {

    //This causes the last cell to be checked for errors

    base.EndEdit();

    if (base.AllowUserToAddRows == true)

    {

    ((BindingSource)base.DataSource).AddNew();

    base.CurrentCell = base.Rows[base.RowCount - 1].Cells[0];

    }

    return true;

    }

    if ((base.CurrentCell.ColumnIndex == (base.ColumnCount - 1)) && (base.CurrentCell.RowIndex + 1 != base.NewRowIndex))

    {

    base.CurrentCell = base.Rows[base.CurrentCell.RowIndex + 1].Cells[1]; // Start at second column

    return true;

    }

    return base.ProcessRightKey(keyData);

    }

    return base.ProcessRightKey(keyData);

    }

    Thursday, March 29, 2007 12:13 AM
  • I've copied an pasted the VB code provided by MacKraken(thanks!)  . Dragged a DataGridView control on my form.
    The first Function works perfect!
    The second function doesn't do anything. When editing a cell, after hitting return it still moves down one row.

    Anyone has tried this VB code? ..does it work for you?

    Thanks !
    Sonja

    ==========================================================

    You have to derive the datagridview class to do this.

    First you have to add a new class1.vb to your project and write some code in it:

    Public Class DGVMod

    'this tells this class that is a datagridview
    Inherits System.Windows.Forms.DataGridView

    'this function do the half of job
    'when you hit a key (like return) it transforms like you
    'have been hit the tab key
    'this doent work when you are editing the cell

    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean

    If keyData = Keys.Return Then
    keyData = Keys.Tab
    With msg
    .WParam = Keys.Tab
    End With
    End If

    Return MyBase.ProcessCmdKey(msg, keyData)
    End Function

    'this second function works when you are editing the cell
    'does the same as the function above changing return for tab
    Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean

    If keyData = Keys.Return Then
    keyData = Keys.Tab
    End If

    Return MyBase.ProcessDialogKey(keyData)
    End Function

    End Class

    Compile your project. You have to drag your new DGVMod control from the toolbox to your form and its done.


    Wednesday, August 15, 2007 1:45 PM
  • Here is what I need. I want the cell to stay at the current selected cell instead of going down to the next row. In c#. Do I need to derive a class and override methods for this or is there an easier way? I did notice like someone else mentioned that when you press Control+Enter you get the desired behavior.

    Any ideas?

    Tuesday, September 18, 2007 2:31 AM
  • Try the following code. I have a datagridview with 8 columns. if the user enters CC in the 1st column, the 2nd column is made read only.after the 4th column, the cursor goes to the 6th column.

     

    Public Class Form1

     

    Private grid_editingrow As Integer = -1

     

    Private Sub DataGridView1_DefaultValuesNeeded(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowEventArgs) Handles DataGridView1.DefaultValuesNeeded

    Dim i As Integer

    With e.Row

    For i = 0 To DataGridView1.Columns.Count - 1

    .Cells(i).Value = ""

    Next

    End With

    End Sub

     

    Private Sub datagridview1_EditingControlShowing(ByVal _

    sender As Object, ByVal e As _

    System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) _

    Handles datagridview1.EditingControlShowing

    grid_editingrow = datagridview1.CurrentRow.Index

    End Sub

     

     

    Private Sub datagridview1_SelectionChanged(ByVal sender As _

    Object, ByVal e As System.EventArgs) Handles _

    datagridview1.SelectionChanged

    Dim x As Integer, r As Integer

    If grid_editingrow >= 0 Then

    Dim new_row As Integer = grid_editingrow

    r = DataGridView1.CurrentCell.ColumnIndex

    x = DataGridView1.CurrentCell.ColumnIndex + 1

    If r = 1 Or (Trim(DataGridView1.Rows(new_row).Cells(1).Value.ToString) <> "CC" And DataGridView1.Rows(new_row).Cells(2).ReadOnly = False) Then

    If Trim(DataGridView1.Rows(new_row).Cells(1).Value.ToString) = "CC" Then

    DataGridView1.Rows(new_row).Cells(2).ReadOnly = False

    Else

    DataGridView1.Rows(new_row).Cells(2).Value = ""

    DataGridView1.Rows(new_row).Cells(2).ReadOnly = True

    End If

    End If

    If r = 4 Then

    x = 6

    End If

    If x > (DataGridView1.Columns.Count - 1) Then

    x = 0

    new_row += 1

    End If

    DataGridView1.CurrentCell = DataGridView1.Rows(new_row).Cells(x)

    grid_editingrow = -1

     

    End If

    End Sub

     

     

    Private Sub datagridview1_KeyDown(ByVal sender As Object, _

    ByVal e As System.Windows.Forms.KeyEventArgs) Handles _

    DataGridView1.KeyDown

    Dim x As Integer, r As Integer

    If e.KeyCode = Keys.Return Then

    Dim cur_cell As DataGridViewCell = _

    DataGridView1.CurrentCell

    Dim new_row As Integer = cur_cell.RowIndex

    x = cur_cell.ColumnIndex + 1

    r = cur_cell.ColumnIndex

    If r = 1 Or (Trim(DataGridView1.Rows(new_row).Cells(1).Value.ToString) <> "CC" And DataGridView1.Rows(new_row).Cells(2).ReadOnly = False) Then

    If Trim(DataGridView1.Rows(new_row).Cells(1).Value.ToString) = "CC" Then

    DataGridView1.Rows(new_row).Cells(2).ReadOnly = False

    Else

    DataGridView1.Rows(new_row).Cells(2).Value = ""

    DataGridView1.Rows(new_row).Cells(2).ReadOnly = True

    End If

    End If

    If r = 4 Then

    x = 6

    End If

    If x > (DataGridView1.Columns.Count - 1) Then

    x = 0

    new_row += 1

    If new_row > (DataGridView1.RowCount - 1) Then

    new_row -= 1

    End If

    End If

    DataGridView1.Refresh()

    DataGridView1.CurrentCell = DataGridView1.Rows(new_row).Cells(x)

    grid_editingrow = -1

    e.Handled = True

    End If

    End Sub

    End Class

    Thursday, December 13, 2007 7:27 AM
  • Hi Pls help me in this,  above code u specified to inherit DataGridView class but in my form i have already inherited a Form class so i can't inherite DGV class.... in this case it throws an error like ProcessDataGridViewKey is not valid or something like that. I'm in C# ..

     

    Pls do reply me...

    Wednesday, February 06, 2008 8:00 AM
  •  

    Hi can u help me in this, i have already derived Form class so that i can not derive another datagridview class in my form.. Whot should i do in this case and pls do reply me...
    Wednesday, February 06, 2008 8:35 AM
  • Well, it seems you are a little bit mistaken on this one.

    You have to create a new class that will inherit from DataGridView. You will not derive a form from DataGridView.

    After you created the new class, which derives from DataGridView it should be available on the toolbar for you to drag onto your form.

    Hope this helps. Smile
    Monday, February 18, 2008 2:24 PM
  • I briefly skimmed over the posts here and i though i would post this as it relates to the editing and control of cell data.

    A few days ago i came up with a little something to use a textbox from the toolbox set to multiline as a custom editing control for whatever cell you have selected.  This will give you the ability to use other controls as well.  The reason i wanted this functionality is to be able to handle the data enterd into the cells as it is being typed and not having to wait for a data error and handle that.  And in the future i plan on using a single combobox or listbox to select from for all cells in a particular column.  This can elininate a lot of painting and increase speed. 

     

    Doing it this way you can control the navigation of the cells with the textbox keypress events as well.

     

    I hope this will help out here.

    Jeff

     

     

     

    Public Class Form1

     

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

     

            Me.DataGridView1.Hide()

     

            Me.DataGridView1.Columns.Add("1", "1")

            Me.DataGridView1.Columns.Add("2", "2")

     

            Dim rw As DataGridViewRow

     

            For i As Integer = 0 To 4

                rw = New DataGridViewRow

                rw.CreateCells(Me.DataGridView1)

                rw.Cells(0).Value = i.ToString

                rw.Cells(1).Value = i.ToString

                Me.DataGridView1.Rows.Add(rw)

            Next

     

            Me.DataGridView1.Show()

     

            Me.TextBox1.Hide()

     

        End Sub

     

        Private Sub DataGridView1_CellBeginEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles DataGridView1.CellBeginEdit

     

            e.Cancel = True

            Me.TextBox1.Show()

            'Me.TextBox1.Text = Me.DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value.ToString

            'Me.TextBox1.Select()

            'Me.TextBox1.SelectionStart = Me.TextBox1.TextLength

     

        End Sub

     

        Dim col As Integer = 0

        Dim rw As Integer = 0

     

        Dim xloc As Integer = 0

        Dim yloc As Integer = 0

     

        Private Sub DataGridView1_CellEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEnter

     

            xloc = Me.DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True).Location.X + 24

            yloc = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True).Location.Y + 54

     

            Me.TextBox1.Size = Me.DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, True).Size

     

            Me.TextBox1.Location = New Point(xloc, yloc)

     

            col = e.ColumnIndex

            rw = e.RowIndex  

     

        End Sub

     

     

        Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress

     

            If e.KeyChar = Chr(13) Then

                e.Handled = True

                Me.DataGridView1.Item(col, rw).Value = CInt(Me.TextBox1.Text)

                Me.TextBox1.Clear()

                Me.TextBox1.Hide()

            ElseIf e.KeyChar = Chr(8) Then

                e.Handled = False

            ElseIf Not IsNumeric(e.KeyChar) Then

                e.Handled = True

            End If

     

        End Sub

     

        Private Sub DataGridView1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles DataGridView1.KeyPress

     

            Me.TextBox1.Text = e.KeyChar

            Me.TextBox1.Select()

            Me.TextBox1.SelectionStart = Me.TextBox1.TextLength

     

        End Sub

    End Class

     

     

     I

     I

     I

     I

    \ /

    Monday, February 18, 2008 9:39 PM
  •  

    Sorry for so many questions....

     

     

    I have put it in a seperate form but it is not available in toolbar

    Tuesday, February 19, 2008 12:56 PM
  • Hi Srinig,

    You will have to build the project first (Build Menu). Than only the new dgv control will appear in toolbox.

    rajeev

    Thursday, February 21, 2008 2:09 PM
  • Thanks rajeev now its working fine!

     

    Wednesday, February 27, 2008 8:44 AM
  • Hi MacKraken,

    I use your code, it's ok but I cannot handle the events with this custom datagrid view object just created, it says:

    Error 6 Handles clause requires a WithEvents variable defined in the containing type or one of its base types. 

     

    can you help me

     

    regards

    Andrea

     

    Thursday, March 27, 2008 11:44 AM
  •  

    Sorry for being late.

     

    Now, your form is a class that can contain different controls that also are classes. The form is a class, the dgv is another type of class.. and so on. So if you edit your dgv control you can handle processdatagridviewkey that is inherit to a datagrid view class.

     

    Hope this helps.

     

    Thursday, March 27, 2008 1:14 PM
  • DGV has many types of builtin events that u can handle. Also you can make custom events. If you are working with that builtin events maybe theres some error on the code or the event clause. Try to delete the event, create it again and write the code in. so vb writes the event clause again.

     

    I think that Overrides dont have to modify another dgv built in events, so it have to work whatever you are tryin to. If your event have to do with the override like "subs enter for tab at changing the cell" you should write your code into the override.

     

    Hope this help you Andrea.

    Greets. 

    Thursday, March 27, 2008 1:29 PM
  • Hi, maybe etter then

    Code Snippet
    ((BindingSource)base.DataSource).AddNew();

     

     

    is:

     

    Code Snippet

    base.BeginEdit(true);

    base.NotifyCurrentCellDirty(true);

    base.EndEdit();

     

     

    So, I have

     

    Code Snippet

    if (keyCode == Keys.Enter)

    { if (base.CurrentCell.ColumnIndex == (base.ColumnCount - 1))

    {

    int row = base.CurrentCell.RowIndex;

    if (row == base.NewRowIndex)

    {

    base.BeginEdit(true);

    base.NotifyCurrentCellDirty(true);

    base.EndEdit();

    base.CurrentCell = base[0, row];

    return base.ProcessDownKey(Keys.Down);

    }

    base.CurrentCell = base[0, row + 1];

    return true;

    }

    return base.ProcessRightKey(keyData);

    }

     

     

    Thursday, August 07, 2008 8:00 AM
  •   Working well


      public class DataGridViewEnter : DataGridView
      {
       protected override bool ProcessDialogKey(Keys keyData)
       {
        Keys key = (keyData & Keys.KeyCode);
        if (key == Keys.Enter)
        {
         return this.ProcessTabKey(keyData);
        }
        return base.ProcessDialogKey(keyData);
       }
       protected override bool ProcessDataGridViewKey(KeyEventArgs e)
       {
        if (e.KeyCode == Keys.Enter)
        {
         return this.ProcessTabKey(e.KeyData);
        }
        return base.ProcessDataGridViewKey(e);
       }
      }

    William
    Monday, October 27, 2008 11:40 AM
  •  Paul Diterwich wrote:

    Adjusted version where the last cell is also being checked...

    public class DataGridViewEnter : DataGridView

    {
    //This override causes the DataGridView to use the enter key in a similar way as
    //the tab key


    protected override bool ProcessDialogKey(Keys keyData)
    {
    Keys key = (keyData & Keys.KeyCode);

    if (key == Keys.Enter)
    {
       return this.ProcessRightKey(keyData);
    }
    return base.ProcessDialogKey(keyData);
    }


    public new bool ProcessRightKey(Keys keyData)
    {
    Keys key = (keyData & Keys.KeyCode);

    if (key == Keys.Enter)
    {
    if ((base.CurrentCell.ColumnIndex == (base.ColumnCount - 1)) && (base.CurrentCell.RowIndex == (base.RowCount - 1)))
    {

    //This causes the last cell to be checked for errors
    base.EndEdit();
    ((BindingSource)base.DataSource).AddNew();
    base.CurrentCell = base.Rows[base.RowCount - 1].Cells[0];
    return true;
    }

    if ((base.CurrentCell.ColumnIndex == (base.ColumnCount - 1)) && (base.CurrentCell.RowIndex + 1 != base.NewRowIndex))
    {
    base.CurrentCell = base.Rows[base.CurrentCell.RowIndex + 1].Cells[0];
    return true;
    }
    return base.ProcessRightKey(keyData);
    }
    return base.ProcessRightKey(keyData);
    }


    protected override bool ProcessDataGridViewKey(KeyEventArgs e)
    {

    if (e.KeyCode == Keys.Enter)
    {
       return this.ProcessRightKey(e.KeyData);
    }
       return base.ProcessDataGridViewKey(e);
    }

    }

     



    This doesn't work for me because i can reorder columns.

    I have(had) a problem with accepting Enter key when in edit mode as all the other users on this thread.

    I have handled most of the problems but the last one with accepting Enter key when the last column is being edited still remains.

    My editing controls are custom and validation is conducted within that custom controls. I have created Process dialog key in CustomDataGridView(inherites DatagridView) that catches Enter but when i write:

    if ((base.CurrentCell.ColumnIndex == (base.ColumnCount - 1)) && (base.CurrentCell.RowIndex == (base.RowCount - 1)))

    it can't get the last column index. Is there some field or property like "FirstDisplayedScrollingColumnIndex" that shows first column, i can't find it(is it possible that FirstDisplayedScrollingColumnIndex exists but not something like LastDisplayedScrollingColumnIndex!?!?!??!

    Also, when i catch enter, only cellEndEdit fires(so i can't do much there), and events like setValue or CellValidating doesn't, so in CellEndEdit i get Value null(this is the moment where i am on last column and pressing enter without any value entered).

    I am also working in virtual mode.

    If some additional information is required to understand my problem please ask.

    Thank you.

    P.S. To summarize, my problem is this:

    When I am in edit mode of cell(string, float, int) with the last column(not index, but as it is previewed in grid) and i hit Enter, nothing happens, that is, none of the events that fire regularly.

    P.S.S. Ok, i found the last displayed column index, DOH. Its:

    if ((base.Columns[CurrentCell.ColumnIndex].DisplayIndex == base.ColumnCount - 1))

    but i still have a problem presented in P.S.

    Tuesday, October 28, 2008 10:52 AM
  • I thought I'd share the aproach I used for a similar problem (although ours was to do with validation rather than navigation).  I exposed an event and raised it from the ProcessDialogKey function.  That way you can decide what to do in the form that uses the grid rather than hard coding the behaviour into grid itself.  Since you'll likely want your grid to behave slightly differentlty depending on where you use it this would be far more flexible.  Otherwise you'll have to create loads of custom implementations of the grid or a single implementation with loads of properties to cover all your scenarios.

    I'm typing this from a machine without VS so can't cut and paste.  Please forgive any typos:-
    Public Event CustomKeyPressed(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys, ByRef Processed As Boolean)

    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
            Dim processed As Boolean = False
            RaiseEvent CustomKeyPressed(msg, keyData, processed)
            If Not processed Then
                Return MyBase.ProcessCmdKey(msg, keyData)
            End If
        End Function


    Now the CustomKeyPressed event will fire whether you're in edit mode or not.  NB, the navigation behaviour is actually processed by the ProcessDataGridViewKey function so you would probably want to apply a similar technique to that.
    Tuesday, January 13, 2009 1:08 PM
  • Thanks for the code, it worked very well. The only change I made was instead of using "processRIGHTkey" I used "processTABKey". The right key moves the cursor within the cell when you hit enter, but I want it to tab to the next cell when you hit enter. Thanks once again
    Thursday, June 25, 2009 4:11 PM
  • To handle the KeyDown and KeyPress events for the editing control just handle the EditingControlShowing event and access the events on the editing control. Check out the DataGridView faq for more info: http://www.windowsforms.net/Samples/Go%20To%20Market/DataGridView/DataGridView%20FAQ.doc

    That said, you do have to derive from the DataGridView to do what you want. This is due to the way that keyboard handling works for contained controls. In a future version of the DataGridView we would like to add a few more events (yeah!) to help make this scenario easier to do.
     
    Here is the code you need to make the Enter key move the focus to the right:

       
    public class dgv : DataGridView
    {
        protected override bool ProcessDialogKey(Keys keyData)
        {
            Keys key = (keyData & Keys.KeyCode);
            if (key == Keys.Enter)
            {
                return this.ProcessRightKey(keyData);
            }
            return base.ProcessDialogKey(keyData);
        }
        protected override bool ProcessDataGridViewKey(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                return this.ProcessRightKey(e.KeyData);
            }
            return base.ProcessDataGridViewKey(e);
        }
    }

     


    -mark

     

    DataGridView Program Manager

    Microsoft

    This post is provided “as-is”

    sorry, to ask u 
    where this code i should paste, i can't get it.

    Thursday, December 10, 2009 10:03 AM
  • Sorry,

    I want to try this code  but i paste it on my code and it doesnt works =(

    can anybody help me please ?
    Wednesday, January 13, 2010 1:12 AM
  • Mark,

       Is there a VB 2005 version of this...  I do not see a direct translation

    Thanks

    Paul

    Friday, March 26, 2010 1:53 PM
  • Hi , Mark

    Actually I am new to this

    And i Don't Know How to use the code which you have given above please tell me how should i use it.

     

    i will very thankful to You....... 

     

    Tuesday, August 23, 2011 5:02 AM