3
votes

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.

1
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
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
@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
hey Corey did you ever find a solution? if so can you plz share it?Max Eisenhardt

1 Answers

4
votes

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;
    }
}