Without the need to create a custom datagrid, you can track the selected row indices and deselect the row if it is not valid in the RowStateChanged event. This involves choosing a cap.
You will also need to add some validation logic when selecting a row to ensure that it does not create a gap in adjacent rows. For example, row 1,2,3 is selected, then row 2 is canceled, so you will either need to prohibit this, or deselect row 3 or row 1.
public List<int> selectedIndexes = new List<int>(); private void dataGridView1_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e) { if (e.StateChanged == DataGridViewElementStates.Selected) { //selected if (e.Row.Selected) { int newRowIndex = e.Row.Index; //if other rows selected make sure adjacent selection exists if (selectedIndexes.Count() > 0) { if (selectedIndexes.Contains(newRowIndex - 1) || selectedIndexes.Contains(newRowIndex + 1)) { //allow selection selectedIndexes.Add(newRowIndex); } else { //cancel selection e.Row.Selected = false; } } else { //first selection so allow it selectedIndexes.Add(newRowIndex); } } else if( !e.Row.Selected) { //row deselected (need to add logic to remove non adjacent rows to be unselected as well) selectedIndexes.Remove(e.Row.Index); } }
}
source share