【问题标题】:DataGridView KeyDown manipulation (enter, left, right, etc.) not working when multiselectDataGridView KeyDown 操作(输入、左、右等)在多选时不起作用
【发布时间】:2015-06-16 17:42:18
【问题描述】:

我想让DataGridView 在操作KeyDown 事件时更方便,例如KeyEnter 用于向右移动一个单元格,或者使用向左、向下或向上。我有一些特殊的用例,我想首先检查单元格,然后我可以丢弃这个事件,或者将它指向另一个单元格。在我将“多选”功能设置为 true 之前,这一切正常。然后离开焦点并设置正确焦点的完整过程,每个单元格不再正常工作。请在下面找到一些示例代码:

private bool GridNavigation(Keys keys)
    {
        if (dataGridView1.CurrentRow == null)
        {
            return true;
        }

        int iColumn = dataGridView1.CurrentCell.ColumnIndex;
        int iRow = dataGridView1.CurrentCell.RowIndex;

        if (keys == Keys.Enter || keys == Keys.Right)
        {
                for (int i = iColumn + 1; i <= dataGridView1.Columns.Count - 4; i++)
                {
                    if (!dataGridView1.Rows[iRow].Cells[i].ReadOnly)
                    {
                        dataGridView1.Rows[iRow].Cells[i].Selected = true;
                        break;
                    }
                    if (i == dataGridView1.Columns.Count - 4 && dataGridView1.Rows.Count - 1 != iRow)
                    {
                        if (((IDictionary<int, int>)dataGridView1.CurrentRow.Tag).SingleOrDefault(p => p.Key == (int)clsDefinitions.ZeilenIndikator.Typ).Value == (int)clsDefinitions.ZeilenTyp.PassLängeAusgangswert)
                            dataGridView1.CurrentCell = dataGridView1[0, iRow + 2];
                        else
                            dataGridView1.CurrentCell = dataGridView1[0, iRow + 1];
                        return true;
                    }
            }
            return true;
        }
        else if (keys == Keys.Left)
        {
            for (int i = iColumn - 1; i >= 0; i--)
            {
                if (!dataGridView1.Rows[iRow].Cells[i].ReadOnly)
                {
                    dataGridView1.Rows[iRow].Cells[i].Selected = true;
                    break;
                }
            }
            return true;
        }
        else
            return false;
    }

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (keyData == Keys.Enter || keyData == Keys.Right || keyData == Keys.Left)
        {
            return GridNavigation(keyData);
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }

那么这里可以做什么。您可以通过打开一个新项目轻松重现,只需在表单中输入 DataGridView 并添加例如 10 列或更多列。

如果还有什么我可以提供的,请告诉我。

【问题讨论】:

  • if (((IDictionary&lt;int, int&gt;)dataGridView1.CurrentRow.Tag).SingleOrDefault(p =&gt; p.Key == (int)clsDefinitions.ZeilenIndikator.Typ).Value == (int)clsDefinitions.ZeilenTyp.PassLängeAusgangswert) 在复制您的输出时我们需要知道什么特别之处吗?
  • 不,没什么特别的。它检查该行是否具有存储在 Row.Tag 下的特殊标志集。因此,如果有一个特殊的标签,例如你提到的那个,它会跳两行而不是一行。但这对我描述的问题并没有真正的影响。希望这会有所帮助。

标签: c# winforms datagridview multi-select


【解决方案1】:

在您的GridNavigation 方法中,在if (keys == Keys.Enter || keys == Keys.Right)else if (keys == Keys.Left) 这两种情况下,有罪的一方是重复行:

dataGridView1.Rows[iRow].Cells[i].Selected = true;

出了什么问题?

dataGridView1.MultiSelect == false 上面的行有效地设置了当前单元格,而不仅仅是Selected 属性。即:

  1. CurrentCell = Rows[0].Cells[0], Rows[0].Cells[0].Selected = true
  2. 用户点击-&gt;回车
    • Rows[0].Cells[1].Selected = true
    • CurrentCell = Rows[0].Cells[1]
    • Rows[0].Cells[0].Selected = false

但是,当dataGridView1.MultiSelect == true 同一行代码设置当前单元格。因此,当前单元格以及左侧或右侧的相邻单元格分别保持选中状态。即:

  1. CurrentCell = Rows[0].Cells[0], Rows[0].Cells[0].Selected = true
  2. 用户点击-&gt;回车
    • Rows[0].Cells[1].Selected = true
    • CurrentCell = Rows[0].Cells[0]
    • Rows[0].Cells[0].Selected = true
  3. 用户再次点击-&gt;回车
    • 预期结果:Rows[0].Cells[2].Selected = true
    • 实际结果:Rows[0].Cells[1].Selected = true ...再次。

解决方案

如果您希望它的行为与 MultiSelect = false 相同,并且在您向左或向右导航时只选择 一个 单元格,只需将有罪的代码行替换为:

dataGridView1.CurrentCell = dataGridView.Rows[iRow].Cells[i];

如果要保留之前选择的单元格,请将有罪的代码行替换为:

DataGridViewSelectedCellCollection cells = dataGridView1.SelectedCells;
dataGridView1.CurrentCell = dataGridView1.Rows[iRow].Cells[i];

if (dataGridView1.MultiSelect)
{
  foreach (DataGridViewCell cell in cells)
  {
    cell.Selected = true;
  }
}

【讨论】:

  • 优秀。在你的帮助下,我得到了它。非常感谢您的快速回复和非常详细的解释。令人印象深刻!
【解决方案2】:

你设置了选择模式吗?

dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-15
    • 2011-05-16
    • 1970-01-01
    • 2012-06-05
    • 2013-05-10
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    相关资源
    最近更新 更多