Sukanya
Sukanya

Reputation: 1061

How to move focus on next cell in a datagridview on Enter key press event

Friends, I'm working on windows application using C#. I'm using a datagridview to display records. The functionality I need is when I press "Enter" key the focus should go to the next cell(column of same row). If it's the last column in the grid then the focus should go to the first column of the next row. I've already tried using

    SendKeys.Send("{Tab}")

in datagridview1_KeyDown and datagridview1_KeyPress event. But focus is moving diagonally down. Please help me to solve this.

Upvotes: 13

Views: 84673

Answers (6)

kgzdev
kgzdev

Reputation: 2885

Posting a bit modified version of @Amritpal Singhs' answer.

If you have hidden(Visible=false) columns as a last column of your grid, then @Amritpal Singhs' solution will throw an error. Below solution takes into account those hidden columns and works without exception:

private void gridDetails_SelectionChanged(object sender, EventArgs e)
{
   if (MouseButtons != 0) return;

   if (_lastCellEndEdit != null && gridDetails.CurrentCell != null)
   {
       // if we are currently in the next line of last edit cell
       if (gridDetails.CurrentCell.RowIndex == _lastCellEndEdit.RowIndex + 1 &&
           gridDetails.CurrentCell.ColumnIndex == _lastCellEndEdit.ColumnIndex)
       {
           int iColNew;
           int iRowNew = 0;

           var lastCellEndEditColumn = gridDetails.Columns[_lastCellEndEdit.ColumnIndex];
           if (lastCellEndEditColumn.DisplayIndex >= GetVisibleColumnsMaxDisplayIndex())
           {
               iColNew = GetFirstVisibleColumnIndex();
               iRowNew = gridDetails.CurrentCell.RowIndex;
           }
           else
           {
               iColNew = GetNextVisibleColumnIndex(lastCellEndEditColumn.DisplayIndex);
               iRowNew = _lastCellEndEdit.RowIndex;
           }
           gridDetails.CurrentCell = gridDetails[iColNew, iRowNew];
       }
   }
   _lastCellEndEdit = null;

}

private DataGridViewCell _lastCellEndEdit;

private void gridDetails_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
   _lastCellEndEdit = gridDetails[e.ColumnIndex, e.RowIndex];
}

int GetVisibleColumnsMaxDisplayIndex()
{
   int maxDisplayIndex = -1;
   foreach (DataGridViewColumn column in gridDetails.Columns)
   {
       if (column.Visible && column.DisplayIndex > maxDisplayIndex)
       {
           maxDisplayIndex = column.DisplayIndex ;
       }
   }
   return maxDisplayIndex;
}

int GetFirstVisibleColumnIndex()
{
   var firstVisibleColumnDisplayIndex = gridDetails.Columns.Count - 1;
   var firstVisibleColumnIndex = 0;
   foreach (DataGridViewColumn column in gridDetails.Columns)
   {
       if (column.Visible && column.DisplayIndex < firstVisibleColumnDisplayIndex)
       {
           firstVisibleColumnDisplayIndex = column.DisplayIndex;
           firstVisibleColumnIndex = column.Index;
       }
   }
   return firstVisibleColumnIndex;
}

int GetNextVisibleColumnIndex(int previousColumnDisplayIndex)
{
   var nextVisibleColumnDisplayIndex = gridDetails.Columns.Count;
   var nextVisibleColumnIndex = previousColumnDisplayIndex;

   foreach (DataGridViewColumn column in gridDetails.Columns)
   {
       if (column.Visible && column.DisplayIndex > previousColumnDisplayIndex 
           && (column.DisplayIndex - previousColumnDisplayIndex) <= (nextVisibleColumnDisplayIndex - previousColumnDisplayIndex))
       {
           nextVisibleColumnDisplayIndex = column.DisplayIndex;
           nextVisibleColumnIndex = column.Index;
       }
   }
   return nextVisibleColumnIndex;
}

Upvotes: 0

Rijul Sudhir
Rijul Sudhir

Reputation: 2132

Even though the codes I tried moved the focus to next cell, They where effecting the mouse click when the cell was in edit mode. This is what I came up with in the end.

    bool _dgv_list_cellEndEdit = false; // class level variable

    void dataGridView1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyData == Keys.Enter)
        {
            e.SuppressKeyPress=true;
            SendKeys.Send("{Tab}");
        }
    }

    void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
    {
        _dgv_list_cellEndEdit=true;
    }

    void dataGridView1_MouseDown(object sender, MouseEventArgs e)
    {
        _dgv_list_cellEndEdit=false;
    }

    void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    {
        if(_dgv_list_cellEndEdit)
        {
            _dgv_list_cellEndEdit=false;
            SendKeys.Send("{Up}");
            SendKeys.Send("{Tab}");
        }
    }

Upvotes: 0

Kishore Kumar
Kishore Kumar

Reputation: 12884

private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
    e.SuppressKeyPress = true;
    int iColumn = dataGridView1.CurrentCell.ColumnIndex;
    int iRow = dataGridView1.CurrentCell.RowIndex;
    if (iColumn == dataGridView1.Columncount-1)
    {
        if (dataGridView1.RowCount > (iRow + 1))
        {
            dataGridView1.CurrentCell = dataGridView1[1, iRow + 1];
        }
        else
        {
            //focus next control
        }
    }
    else
        dataGridView1.CurrentCell = dataGridView1[iColumn + 1, iRow];
}

Upvotes: 14

Amritpal Singh
Amritpal Singh

Reputation: 1785

you can use selectionchanged event of the datagridview. In your form

       private DataGridViewCell _celWasEndEdit;

        private void datagridview_SelectionChanged(object sender, EventArgs e)
    {

        if (MouseButtons != 0) return;

        if (_celWasEndEdit != null && datagridview.CurrentCell != null)
        {
            // if we are currently in the next line of last edit cell
            if (datagridview.CurrentCell.RowIndex == _celWasEndEdit.RowIndex + 1 &&
                datagridview.CurrentCell.ColumnIndex == _celWasEndEdit.ColumnIndex)
            {
                int iColNew;
                int iRowNew = 0;
                if (_celWasEndEdit.ColumnIndex >= datagridview.ColumnCount - 1)
                {
                    iColNew = 0;
                    iRowNew = dgvItems.CurrentCell.RowIndex;                   
                }
                else
                {
                        iColNew = _celWasEndEdit.ColumnIndex + 1;
                        iRowNew = _celWasEndEdit.RowIndex;
                }
                datagridview.CurrentCell = datagridview[iColNew, iRowNew];
            }
        }
        _celWasEndEdit = null;
      }

    private void datagridview_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    {
        _celWasEndEdit = dgvItems[e.ColumnIndex, e.RowIndex];
    }

Upvotes: 6

Arun Agarwal
Arun Agarwal

Reputation: 805

protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
{
    int icolumn = dataGridView1.CurrentCell.ColumnIndex;
    int irow = dataGridView1.CurrentCell.RowIndex;

    if (keyData == Keys.Enter)
    {                                
        if (icolumn == dataGridView1.Columns.Count - 1)
        {
            dataGridView1.Rows.Add();
            dataGridView1.CurrentCell = dataGridView1[0, irow + 1];
        }
        else
        {
            dataGridView1.CurrentCell = dataGridView1[icolumn + 1, irow];
        }
        return true;
    }
    else
        return base.ProcessCmdKey(ref msg, keyData);
    }
}

Upvotes: 11

YOusaFZai
YOusaFZai

Reputation: 698

bool notlastColumn =true; //class level variable--- to check either last column is reached or not

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    if (dataGridView1.ColumnCount - 1 == e.ColumnIndex)  //if last column
    {
        KeyEventArgs forKeyDown = new KeyEventArgs(Keys.Enter);
        notlastColumn = false;
        dataGridView1_KeyDown(dataGridView1, forKeyDown);
    }
    else
    {
        SendKeys.Send("{up}");
        SendKeys.Send("{right}");
    }
}

private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Enter && notlastColumn) //if not last column move to nex
    {
        SendKeys.Send("{up}");
        SendKeys.Send("{right}");
    }
    else if (e.KeyCode == Keys.Enter)
    {
        SendKeys.Send("{home}");//go to first column
        notlastColumn = true;
    }
}

Upvotes: 2

Related Questions