3

I have a DataGridView with a number of columns and rows. I have MutliSelect enabled, but this allows selection of all cells.

I want to limit the selection vertically, horizontally, full row or full column, but never a mix of both. The user can select by dragging starting at any cell then either vertically or horizontally.

Here's a small diagram to clarify if it helps at all.

Corey
  • 1,177
  • 4
  • 16
  • 24
  • Interesting. I feel like you need to put a little more thought into how you want the grid to react to the user interactions. More specifically, in your 4th example it looks like maybe the user clicked "Bob Acri" (Title) and then shift-clicked "Mr. Scruff". What do you expect the grid to do at that point? Keep just "Bob Acri" selected? Select just "Mr. Scruff"? Create the selection in the first example? Something else? The same could be asked of the last example where the user probably had a legal selection and then ctrl-clicked something illegal. What is the final result supposed to be? – Chuck Wilbur Mar 08 '12 at 03:11
  • I also don't understand why you would ever want this restriction in the first place. If the partial-row selection in the third example is legal, why would the multiple-partial-row fourth example be illegal? – Chuck Wilbur Mar 08 '12 at 03:14
  • @ChuckWilbur Vertical selection is for mass renaming, e.g., if a user wants to select a bunch of song albums and edit them all to be the same value, they can do that. Partial and full horizontal selection would be for various filtering features. – Corey Mar 08 '12 at 03:24
  • hey Corey did you ever find a solution? if so can you plz share it? – Max Eisenhardt Jun 27 '13 at 13:48

1 Answers1

4

Here's the brute force method - when the selection changes, de-select any cells that fall outside the current row/column selection:

int _selectedRow = -1;
int _selectedColumn = -1;
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
    switch (dataGridView1.SelectedCells.Count)
    {
        case 0:
            // store no current selection
            _selectedRow = -1;
            _selectedColumn = -1;
            return;
        case 1:
            // store starting point for multi-select
            _selectedRow = dataGridView1.SelectedCells[0].RowIndex;
            _selectedColumn = dataGridView1.SelectedCells[0].ColumnIndex;
            return;
    }

    foreach (DataGridViewCell cell in dataGridView1.SelectedCells)
    {
        if (cell.RowIndex == _selectedRow)
        {
            if (cell.ColumnIndex != _selectedColumn)
            {
                _selectedColumn = -1;
            }
        }
        else if (cell.ColumnIndex == _selectedColumn)
        {
            if (cell.RowIndex != _selectedRow)
            {
                _selectedRow = -1;
            }
        }
        // otherwise the cell selection is illegal - de-select
        else cell.Selected = false;
    }
}
Chuck Wilbur
  • 2,510
  • 3
  • 26
  • 35
  • I had a different usage scenario (Only multi select a specific column). I was able to quickly modify this code for my intents. This should be rated as the correct answer. – roscoe_casita Apr 18 '16 at 15:42