Как я могу захватить мышь в DataGridViewRow, чтобы она двигалась только внутри строки

Я пишу приложение для резервирования, которое использует DataGridView для перечисления доступных комнат по оси Y и доступного времени по оси X в качестве столбцов.

Я хотел бы, чтобы пользователь мог перетаскивать выбранный период времени, но он должен быть ограничен одной строкой за раз.

Либо управление аспектом выделения сетки, чтобы при перемещении мыши выделялась только нужная строка, либо захват мыши в пределах границ строк - вот варианты, о которых я подумал. Любая помощь в реализации любого из этих или даже новый способ справиться с задачей приветствуются!

Я бы предпочел просто захватить мышь с помощью DataRow, где происходит событие нажатия мыши, не уверенный, должен ли я использовать прямоугольник отсечения для достижения этого или нет.

Заранее благодарю за любую помощь.

2 ответа

Решение

В качестве улучшения вашего кода события 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
      }
    }
    */
  }
}

Разницами в этом цикле является использование e.Cell в качестве ориентира для RowIndex поскольку e.Cell является ячейкой, выбранной пользователем, настройка e.Cell.Selected в false вместо cell.Selected и, наконец, break; в цикле, так как после первого RowIndex несоответствие, мы можем остановить проверку.

Вероятно, лучший способ написать это, но это работает.

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;
                }
            }
        }
    }
Другие вопросы по тегам