none
How to Handle DatagridView's keydown event during editing of cell on Enter key Press RRS feed

  • Question

  •  

    Dear

           expert can anybody tell me how can i handle  Datagridview's Keydown Event

           after editing cell on Enter key Press.

          

     

          my datagridview should be used for user input .some cell r readonly and some

          r user input. my problem is i can't set focus after input one cell & redirect cursor another cell

             [ e.g cell 0 -- go to  cell 4 - cell 7 & again next row start cell 0 ]

     

     

        i have seen handling enter as like tab key in other thread but it not solved my problem

            

          if anybody know how to do please tell

         thank

    Thursday, July 3, 2008 9:20 AM

Answers

  •  

    Hi

    You can try to implement the IMessageFilter to your form to capture the WM_KEYDOWN message. And change the current cell of you DataGridView control if the user presses enter key.

    Code Snippet

        public partial class Form1 : Form,IMessageFilter

        {

            public Form1()

            {

                InitializeComponent();

            }

     

     

            #region IMessageFilter Members

            private const UInt32 WM_KEYDOWN = 0x0100;

            public bool PreFilterMessage(ref Message m)

            {

                if (m.Msg == WM_KEYDOWN)

                {

                    Keys keyCode = (Keys)(int)m.WParam & Keys.KeyCode;

                    if (keyCode == Keys.Enter)

                    {

                        if (this.dataGridView1.CurrentCell.ColumnIndex == 0 && this.dataGridView1.Columns.Count >= 5)

                            this.dataGridView1.CurrentCell = this.dataGridView1[4, this.dataGridView1.CurrentCell.RowIndex];

                        else if (this.dataGridView1.CurrentCell.ColumnIndex == 4 && this.dataGridView1.Columns.Count >= 8)

                            this.dataGridView1.CurrentCell = this.dataGridView1[7, this.dataGridView1.CurrentCell.RowIndex];

                        return true;

                    }

                    return false;

                }

                return false;

            }

            #endregion

     

            private void Form1_Load(object sender, EventArgs e)

            {

                DataTable dt = new DataTable();

                dt.Columns.Add("col1");

                dt.Columns.Add("col2");

                dt.Columns.Add("col3");

                dt.Columns.Add("col4");

                dt.Columns.Add("col5");

                dt.Columns.Add("col6");

                dt.Columns.Add("col7");

                dt.Columns.Add("col8");

                dt.Columns.Add("col9");

                this.dataGridView1.DataSource = dt;

                Application.AddMessageFilter(this);

            }

     

            private void Form1_FormClosed(object sender, FormClosedEventArgs e)

            {

                Application.RemoveMessageFilter(this);

            }

        }

     

    Hope this helps.
    Best regards.
    Rong-Chun Zhang

    Windows Forms General FAQs
    Windows Forms Data Controls and Databinding FAQs

    Wednesday, July 9, 2008 12:14 PM

All replies

  • In the EditingControlShowing event you can add a handler to the keypress event for the textbox.  Make sure you remove the old handler before adding a new one.

     

    There is an example in this thread

     

    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1744806&SiteID=1

    Thursday, July 3, 2008 11:05 AM
  • i know what y r saying but my problem is that i want to set focus on particular cell after inputting

    some value on one cell & then directly go another cell on single enter key press.

     

    i have done this type functionality with double enter key press. what happened when i edit in one cell then i have to

     press twice enter key press before focus on another cell.

     

    i just want to on single enter keypress

     

    my code.. here..........

     

     

     

     

    private void grdDtailsGrid_KeyDown(object sender, KeyEventArgs e)

    {

    strTempMode = lblMode.Text;

    try

    {

    if (e.KeyCode == Keys.F1 && grdDtailsGrid.CurrentCell.ColumnIndex == (int)enmTrnSaleGrid.Style_No)

    {

    setHelpGrid();

    }

    //put Cursor in particular column after entering data in DGV(Details Grid) Cell on enter keypress

    if (e.KeyCode == Keys.Enter)

    {

    //Get current cell of DGV Control

    DataGridViewCell grdCell = grdDtailsGrid.CurrentCell;

    int intColumnIndex = grdCell.ColumnIndex;

    //Set Focus of curcusor to particular cell

    if ((intColumnIndex == (int)enmTrnSaleGrid.Style_No) || (intColumnIndex == (int)enmTrnSaleGrid.Item_Name))

    {

    grdDtailsGrid.CurrentCell = grdDtailsGrid[(int)enmTrnSaleGrid.No_Of_Boxes, grdDtailsGrid.CurrentRow.Index];

    }

    if (intColumnIndex == (int)enmTrnSaleGrid.No_Of_Boxes)

    {

    if (grdCell.RowIndex == grdDtailsGrid.RowCount - 1) //Supress to add new row when already exists a new row

    {

    if (grdCell.FormattedValue.ToString().Trim() != "") // check if user has input some data

    {

    if (strTempMode == Mode.gcAdd)

    {

    if (string.IsNullOrEmpty(grdDtailsGrid[(int)enmTrnSaleGrid.Style_No, grdCell.RowIndex].FormattedValue.ToString().Trim()) == false)

    {

    grdDtailsGrid.Rows.Add("");

    grdDtailsGrid.CurrentCell = grdDtailsGrid[(int)enmTrnSaleGrid.Style_No, grdDtailsGrid.CurrentRow.Index + 1];

    }

    else

    {

    if (e.KeyCode == Keys.Enter) BtnSave.Focus();

    }

    }

    else if (strTempMode == Mode.gcEdit)

    {

    if (string.IsNullOrEmpty(grdDtailsGrid[(int)enmTrnSaleGrid.Style_No, grdCell.RowIndex].FormattedValue.ToString().Trim()) == false)

    {

    dsetDetailsRecord.Tables[0].Rows.Add(dsetDetailsRecord.Tables[0].NewRow());

    }

    else

    {

    if (e.KeyCode == Keys.Enter) BtnSave.Focus();

    }

    }

    }

    else

    {

    if (e.KeyCode == Keys.Enter) BtnSave.Focus();

    }

    }

    else

    {

    grdDtailsGrid.CurrentCell = grdDtailsGrid[(int)enmTrnSaleGrid.Style_No, grdDtailsGrid.CurrentRow.Index + 1];

    }

    }

     

    e.Handled = true; // Disable DGV's(Details Grid) Cell textbox Enter Key

    }

    else

    if (e.KeyCode == Keys.Delete)

    {

    DialogResult response = MessageBox.Show("Are you sure you want to delete this row?",

    Project.gcProjectName,

    MessageBoxButtons.YesNo,

    MessageBoxIcon.Question,

    MessageBoxDefaultButton.Button2);

    if (response == DialogResult.Yes)

    {

    foreach (DataGridViewRow row in grdDtailsGrid.SelectedRows )

    {

    if (!row.IsNewRow)

    {

    grdDtailsGrid.Rows.Remove(row);

    //CalculateValue();

    //CalculateGrossVATNetAmount();

    }

    }

    foreach (DataGridViewCell cell in grdDtailsGrid.SelectedCells)

    {

    DataGridViewRow cellRow = cell.OwningRow;

    if (!cellRow.IsNewRow)

    {

    grdDtailsGrid.Rows.Remove(cellRow);

    //CalculateValue();

    //CalculateGrossVATNetAmount();

    }

    }

    if (grdDtailsGrid.Rows.Count == 0)

    {

    if (strTempMode == Mode.gcAdd)

    {

    grdDtailsGrid.Rows.Add("");

    }

    else if (strTempMode == Mode.gcEdit)

    {

    dsetDetailsRecord.Tables[0].Rows.Add(dsetDetailsRecord.Tables[0].NewRow());

    }

    }

     

    }

    }

    }

    catch (Exception err_Handler)

    {

    root.gUserMessage(err_Handler.Message);

    }

     

     

     

     

     

     

    //get controls(like textbox,Checkbox,combo etc) inside cell of DGV Control.

    //it will fire when user edit the cell

    private void grdDtailsGrid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)

    {

    e.CellStyle.BackColor = Color.White;

    TextBox txtDGVcell = e.Control as TextBox;

    intEditingRowIndex = grdDtailsGrid.CurrentRow.Index;

    if (txtDGVcell != null)

    {

    // Define & register Event Handler of Textbox control in edit cell

    txtDGVcell.TextChanged -= new EventHandler(txtDGVcell_TextChanged);

    txtDGVcell.TextChanged += new EventHandler(txtDGVcell_TextChanged);

    txtDGVcell.KeyPress -= new KeyPressEventHandler(txtDGVcell_KeyPress);

    txtDGVcell.KeyPress += new KeyPressEventHandler(txtDGVcell_KeyPress);

    }

    }

    private void txtDGVcell_TextChanged(object sender, EventArgs e)

    {

    DataGridViewCell DGVCell = grdDtailsGrid.CurrentCell;

    if (DGVCell.ColumnIndex == (int)enmTrnSaleGrid.No_Of_Boxes)

    {

    ((TextBox)sender).BackColor = Color.White;

    //((TextBox)sender).Invalidate();

    //((TextBox)sender).Update(); // = Color.White;

    //grdDtailsGrid.Update();

    //grdDtailsGrid.Refresh();

    updateQtyNoBox(((TextBox)sender).Text);

    CalculateValue();

    CalculateGrossVATNetAmount();

    txtTotalQuantity.Text = CalculateTotalQuantity(grdDtailsGrid, (int)enmTrnSaleGrid.No_Of_Boxes).ToString();

    }

    }

    private void txtDGVcell_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e)

    {

    //grdDtailsGrid.Refresh();

    if (mainVB.gTextBoxValidation(Convert.ToInt32(e.KeyChar), "N,8,2", (TextBox)sender, "N") == false)

    e.Handled = true;

    }

     

     

     

     

     

     

     

     

     

     

     

     

    Friday, July 4, 2008 5:15 AM
  •  

    Hi arup08,

    You can try to custom a DataGridView inherit from the standard DataGridView and override the ProcessDialogKey method to provide this functionality. I write a simple sample for your information:

    Code Snippet

        public partial class Form1 : Form

        {

            public Form1()

            {

                InitializeComponent();           

            }

     

            private void Form1_Load(object sender, EventArgs e)

            {

                DataTable dt = new DataTable();

                dt.Columns.Add("col1");

                dt.Columns.Add("col2");

                dt.Columns.Add("col3");

                dt.Columns.Add("col4");

                dt.Columns.Add("col5");

                dt.Columns.Add("col6");

                dt.Columns.Add("col7");

                dt.Columns.Add("col8");

                dt.Columns.Add("col9");

                this.myDataGridView1.DataSource = dt;

            }

        }

     

        class MyDataGridView : DataGridView

        {

            protected override bool ProcessDialogKey(Keys keyData)

            {

                //cell is in Edit mode

                if (keyData == Keys.Enter)

                {

                    if (this.CurrentCell.ColumnIndex == 0 && this.Columns.Count >= 5)

                        this.CurrentCell = this[4, this.CurrentCell.RowIndex];

                    else if (this.CurrentCell.ColumnIndex == 4 && this.Columns.Count >= 8)

                        this.CurrentCell = this[7, this.CurrentCell.RowIndex];

                    return true;

                }

                return base.ProcessDialogKey(keyData);

            }

     

            //if you want similar behavior when cell is not in edit mode,

            //you can override ProcessCmdKey method

        }

     

    Hope this helps.
    Best regards.
    Rong-Chun Zhang

    Windows Forms General FAQs
    Windows Forms Data Controls and Databinding FAQs

    Wednesday, July 9, 2008 10:52 AM
  • hi

       rong ,

            first of all thanks for your reply. it will be fixed DGV Column selection.

             but another time my criteria will be changed. so i have to recreate custom DGV

             control each time i nedd differently. have any another way to solve my problem ?.

          

    Wednesday, July 9, 2008 11:21 AM
  •  

    Hi

    You can try to implement the IMessageFilter to your form to capture the WM_KEYDOWN message. And change the current cell of you DataGridView control if the user presses enter key.

    Code Snippet

        public partial class Form1 : Form,IMessageFilter

        {

            public Form1()

            {

                InitializeComponent();

            }

     

     

            #region IMessageFilter Members

            private const UInt32 WM_KEYDOWN = 0x0100;

            public bool PreFilterMessage(ref Message m)

            {

                if (m.Msg == WM_KEYDOWN)

                {

                    Keys keyCode = (Keys)(int)m.WParam & Keys.KeyCode;

                    if (keyCode == Keys.Enter)

                    {

                        if (this.dataGridView1.CurrentCell.ColumnIndex == 0 && this.dataGridView1.Columns.Count >= 5)

                            this.dataGridView1.CurrentCell = this.dataGridView1[4, this.dataGridView1.CurrentCell.RowIndex];

                        else if (this.dataGridView1.CurrentCell.ColumnIndex == 4 && this.dataGridView1.Columns.Count >= 8)

                            this.dataGridView1.CurrentCell = this.dataGridView1[7, this.dataGridView1.CurrentCell.RowIndex];

                        return true;

                    }

                    return false;

                }

                return false;

            }

            #endregion

     

            private void Form1_Load(object sender, EventArgs e)

            {

                DataTable dt = new DataTable();

                dt.Columns.Add("col1");

                dt.Columns.Add("col2");

                dt.Columns.Add("col3");

                dt.Columns.Add("col4");

                dt.Columns.Add("col5");

                dt.Columns.Add("col6");

                dt.Columns.Add("col7");

                dt.Columns.Add("col8");

                dt.Columns.Add("col9");

                this.dataGridView1.DataSource = dt;

                Application.AddMessageFilter(this);

            }

     

            private void Form1_FormClosed(object sender, FormClosedEventArgs e)

            {

                Application.RemoveMessageFilter(this);

            }

        }

     

    Hope this helps.
    Best regards.
    Rong-Chun Zhang

    Windows Forms General FAQs
    Windows Forms Data Controls and Databinding FAQs

    Wednesday, July 9, 2008 12:14 PM
  • thanks rong

                     i have tested your code but problem is that i have lots of control over form

                    so when i press enter for  any other control then this fun gets executed & show error message

                    i think it is not right way to solve that matter

    Thursday, July 10, 2008 4:57 AM
  •  

    Hi arup08,

    Thanks for feedback and sorry for the above solution will act on all the controls on the form. To avoid this problem, we can check if the DataGridView have the focus before you change the current cell.

    Hope this helps.
    Best regards.
    Rong-Chun Zhang

    Windows Forms General FAQs
    Windows Forms Data Controls and Databinding FAQs

    Monday, July 14, 2008 10:56 AM
  • I need to find a solution to the following problem scenario:

     

    I have an editable datagridview cell in edit mode. After entering text in the cell, if I press enter button, then the content of the cell will be validated. If there is any error, that message will be displayed. Otherwise, the focus will go to the next cell of the same row.

     

    Can anyone please give me a solution to this problem scenario.

     

    Thanks in advance...

    jads..

    Tuesday, October 21, 2008 9:13 AM
  • Dear Arup Please send me solution if you have
    Friday, May 3, 2019 11:01 AM