0
votes

I'm running into a problem making multiple selections programmatically in a DataGridView (DGV) based on data table values. I have a table with one column "ID", I need to pass these values to another form with a DGV for editing, ID is the first DGV column also, i.e. for every ID in the table, the appropriate DGV row should be selected. I can loop through the table and DGV fine, but only the last value is selected even though the DGV properties MultiSelect=true ... when I use the form manually, multiple select works fine.

    foreach(DataRow dtrow in dt.Rows)
    {
        string Selection = dtrow["ID"].ToString();
        foreach(DataGridViewRow DGVrow in dgview.Rows)
        {                    
            if (DGVrow.Cells[0].Value.ToString().Equals(Selection))
            {
                dgview.CurrentCell = DGVrow.Cells[0];
                int cellInx = dgview.CurrentCell.RowIndex;
                dgview.Rows[cellInx].Selected = true;                                                                                      
                break;
            }
        }
    }
1
Shouldn't your Selection variable use the dtRow variable? You aren't using the dtRow variable anywhere in your loops.LarsTech
Sorry, that was a typo ... I've updated the code.ArtR45

1 Answers

0
votes

I'm answering my own question because I don't think this is possible on form load. My application has a form that's used to add selections to a project. When the user wants to 'Edit' the project, I need to call this form and make all the previous selections so the user can add/delete. When using a DataGridView (DGV) with multi-select enabled, at run time, you can 'ctl-click' and select multiple items ... essentially I'm trying to recreate this behavior in code, on form load in 'edit' mode. After the form is initialized I have a method that loads the DGV from OleDb tables, to test this out I tried putting the following lines after the load method call and as the last lines of the method call:

        dgv1.Rows[0].Selected = true;
        dgv1.Rows[1].Selected = true;
        dgv1.Rows[2].Selected = true;

Obviously, on form load, I was expecting the first 3 rows to be 'selected', but that didn't happen. However, I remembered a separate issue, I could never get the DGV to load without the first line selected by default ... so I put in a 'refresh' button, that simply calls the 'Load' method again ... the last line of which is: DGV1.Rows[0].Selected = False; With the refresh button the DGV loads without the first line selected. I was curious if this was a similar situation, so when I added these 3 lines to the end of the load method, nothing happened on form load ... but ... when I hit the 'Refresh' button, the first 3 rows were 'selected'.

I've been researching this for over 3 days and found the following from the DataGridView Project Manager (2006): https://social.msdn.microsoft.com/Forums/windows/en-US/cf351d44-4a9a-4c80-8d52-4fb349847908/multiple-select-is-not-working-for-datagridview?forum=winformsdatacontrols

Unfortunately there isn’t an easy solution to this as I didn’t look at this scenario and design the grid to handle this well. The main problem stems from the fact that when you mouse down on the grid, the grid sets the current cell property which clears the selection before selecting the next cell/row/column. So, while your line of code selects the row, when you go to select the next row or just move to the next row using the keyboard, the row you selected is cleared. The easiest way to do your scenario is to use custom painting via the RowPrePaint and paint the “selected” rows using the same SelectedBackground color. You can just query the value of the check box cell in the row that you are painting to know if that row is “selected”, but there isn’t any need to set the Selected property to true. The flip side to this is that you’ll have to keep track or enumerate all rows to know all the “selected” row at a given time. -> mark -> DataGridView Program Manager - 2006

So my plan going forward is to rebuild the DGV to use check boxes, as recommended. I just wanted to put this out there for general information and/or if someone has a better idea. Thanks