winforms 使用cellendedit事件后出现当前单元格焦点问题

aiazj4mn  于 2022-12-14  发布在  其他
关注(0)|答案(1)|浏览(145)

我正在设计一个c# datagridview,其中回车键的作用相当于制表符,返回键的结果是回到上一个单元格。同样,如果焦点在最后一行的最后一个单元格,它会创建一个新行。

private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
  {
     e.SuppressKeyPress = true;
     int iColumn = dataGridView1.CurrentCell.ColumnIndex;
     int iRow = dataGridView1.CurrentCell.RowIndex;
     if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Right || e.KeyCode == Keys.Tab)
     {
         //to check if the pointer reach last column
         if (iColumn == dataGridView1.ColumnCount - 1)
         {
             //executing when line ends                         
             if (dataGridView1.RowCount > (iRow + 1))
             {
                   
                 dataGridView1.CurrentCell = dataGridView1[0, iRow + 1];
             }
                 // fires when you reach last cell of last row and last column 
             else
             {
                    
                 dataGridView1.Rows.Add();
                 dataGridView1.CurrentCell = dataGridView1[0, iRow +1];                  
             }
         }
         else
         {
             dataGridView1.CurrentCell = dataGridView1[iColumn + 1, iRow];
         }
     }
     if (e.KeyCode == Keys.Down)
     {
         int c = dataGridView1.CurrentCell.ColumnIndex;
         int r = dataGridView1.CurrentCell.RowIndex;
         if (r < dataGridView1.Rows.Count - 1) //check for index out of range
             dataGridView1.CurrentCell = dataGridView1[c, r + 1];
     }
     if (e.KeyCode == Keys.Up)
     {
         int c = dataGridView1.CurrentCell.ColumnIndex;
         int r = dataGridView1.CurrentCell.RowIndex;
         if (r > 0) //check for index out of range
             dataGridView1.CurrentCell = dataGridView1[c, r - 1];
     }
     if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Left)
     {
         //to check if you are in first cell of any line 
         if (iColumn == 0)
         {
             //to check if you are in first cell of fist line 
             if (iRow == 0)
             {
                 MessageBox.Show("you reached first cell");
             }
             else
             {
                 dataGridView1.CurrentCell = dataGridView1[dataGridView1.ColumnCount - 1, iRow - 1];
             }
         }
         else
         {
             dataGridView1.CurrentCell = dataGridView1[iColumn - 1, iRow];
         }
     }
 }
Now , after this i want to edit the cell values and want to move to next cell when i press enter key  , so i add  the following event (as i am in cell editing mode due to this, the above key down event will not raise ) 

 private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
 {
     // MOVE TO NEXT CELL WHEN DONE EDITING 
     SendKeys.Send("{right}");
 }

但是在使用了上面的cellendedit事件之后,我发现单元格向下移动到下一行(datagridview的默认行为),然后移动到下一行的下一个单元格(由于cellendedit)。相反,它应该移动到同一行的下一列。请建议我修复这个行为。

9o685dep

9o685dep1#

您的问题是如何取消默认的DataGridView导航并替换为您自己的导航。默认导航出现在OnKeyDown方法中,如果在自定义控件中重写它,(我们称之为DataGridViewEx)您应该能够通过重写该方法来抑制默认导航,确保您 * 没有调用Keys.EnterKeys.Back的基类版本 *。

BindingList<Record> Records = new BindingList<Record>();
protected override void OnKeyDown(KeyEventArgs e)
{
    if (CurrentCell != null)
    {
        var row = CurrentCell.RowIndex;
        var col = CurrentCell.ColumnIndex;
        switch (e.KeyData)
        {
            case Keys.Return:
                col++;
                // [ToDo] Allow for non-visible rows (will fail).
                if(col.Equals(Columns.Count))
                {
                    col = 0;
                    row++;
                    // Either insert after the current row as
                    // shown here, or add to the end of the list.
                    Records.Insert(row, new Record());
                }
                CurrentCell = this[col, row];
                break;
            case Keys.Back:
                col--;
                if(col >= 0)
                {
                    CurrentCell = this[col, row];
                }
                break;
            default:
                base.OnKeyDown(e);
                break;
        }
    }
}

测试台

下面是我在更改MainForm.Designer.cs中的两个条目以使用DataGridViewEx之后测试此解决方案的过程:

namespace current_cell_focus
{
    public partial class MainForm : Form
    {
        public MainForm() => InitializeComponent();
    }

    // Custom control
    class DataGridViewEx : DataGridView
    {
        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            AllowUserToAddRows = false;
            DataSource = Records;

            // Format columns
            Records.Add(new Record());
            foreach (DataGridViewColumn col in Columns)
            {
                col.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            }
            Records.Clear();

            // Load test data
            Records.Add(new Record
            {
                Column1 = "1",
                Column2 = "2",
                Column3 = "3"
            });
            Records.Add(new Record
            {
                Column1 = "4",
                Column2 = "5",
                Column3 = "6"
            });
            Records.Add(new Record
            {
                Column1 = "7",
                Column2 = "8",
                Column3 = "9"
            });
        }
        BindingList<Record> Records = new BindingList<Record>();
        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (CurrentCell != null)
            {
                var row = CurrentCell.RowIndex;
                var col = CurrentCell.ColumnIndex;
                switch (e.KeyData)
                {
                    case Keys.Return:
                        col++;
                        // [ToDo] Allow for non-visible rows (will fail).
                        if(col.Equals(Columns.Count))
                        {
                            col = 0;
                            row++;
                            // Either insert after the current row as
                            // shown here, or add to the end of the list.
                            Records.Insert(row, new Record());
                        }
                        CurrentCell = this[col, row];
                        break;
                    case Keys.Back:
                        col--;
                        if(col >= 0)
                        {
                            CurrentCell = this[col, row];
                        }
                        break;
                    default:
                        base.OnKeyDown(e);
                        break;
                }
            }
        }
    }

    class Record
    {
        public string Column1 { get; set; }
        public string Column2 { get; set; }
        public string Column3 { get; set; }
    }
}

相关问题