如何在DataGridViewRow中捕获鼠标,因此它只在行内移动

时间:2015-04-14 15:08:20

标签: c# winforms datagridview mousecapture

我正在编写一个预约应用程序,它利用DataGridView列出Y轴下的可用房间和X轴上的可用时间列。

我希望用户能够拖动选择一个时间范围,但它必须一次限制为一行。

控制网格的高亮显示方面,以便当鼠标移动或在行边界内捕获鼠标时只突出显示所需的行是我想到的选项。任何这方面的帮助,甚至是处理任务的新方法都是受欢迎的!

我更倾向于使用DataRow捕获鼠标,其中发生鼠标按下事件,不确定是否必须使用剪切矩形来实现此目的。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

写这个可能是一个更好的方法,但它有效。

private void dataGridView1_CellStateChanged(object sender, DataGridViewCellStateChangedEventArgs e)
    {
        if (dataGridView1.SelectedCells.Count > 1)
        {
            //Retrieves the first cell selected
            var startRow = dataGridView1.SelectedCells[dataGridView1.SelectedCells.Count - 1].RowIndex;

            foreach (DataGridViewCell cell in dataGridView1.SelectedCells)
            {
                if (cell.RowIndex != startRow)
                {
                    cell.Selected = false;
                }
            }
        }
    }

答案 1 :(得分:1)

作为对CellStateChanged事件代码的改进,可以使用以下内容。

private void dataGridView1_CellStateChanged(object sender, DataGridViewCellStateChangedEventArgs e)
{
  if ((e.StateChanged == DataGridViewElementStates.Selected) && // Only handle it when the State that changed is Selected
      (dataGridView1.SelectedCells.Count > 1))
  {
    // A LINQ query on the SelectedCells that does the same as the for-loop (might be easier to read, but harder to debug)
    // Use either this or the for-loop, not both
    if (dataGridView1.SelectedCells.Cast<DataGridViewCell>().Where(cell => cell.RowIndex != e.Cell.RowIndex).Count() > 0)
    {
      e.Cell.Selected = false;
    }

    /*
    foreach (DataGridViewCell cell in dataGridView1.SelectedCells)
    {
      if (cell.RowIndex != e.Cell.RowIndex)
      {
        e.Cell.Selected = false;
        break;  // stop the loop as soon as we found one
      }
    }
    */
  }
}

此for循环中的差异是使用e.Cell作为RowIndex的参考点,因为e.Cell是用户选择的单元格,设置为{{1}从e.Cell.Selected代替false,最后在for循环中cell.Selected,因为在第一个break;不匹配之后,我们可以停止检查。