We help IT Professionals succeed at work.

Select multiple rows in a C# DataGridView programmatically?

e_livesay
e_livesay asked
on
9,390 Views
Last Modified: 2013-12-11
I need to select multiple rows in a DataGridView (MultiSelect = true, SelectionMode = RowHeaderSelect). From the user interface there is no problem.  I simply hold down the <CTRL> key and click on all of the row headers one-by-one.  When I click on a row, all of the cells in the row are redrawn with a blue background indicating that they have been selected and the arrow that appears in the row header column is updated so that it is in the last row header that I clicked.

When attempting to replicate this behavior programmaticly I run into a problem.  The code shown below is supposed to do this - first it fills the DataGridView with data (the DataGridView is not DataBound) and second it selects all of the rows.  The System.Diagnostics lines output what I would expect when there are 3 rows in the DataGridView; before = 0 and after = 3. However, on the UserInterface the background of the cells in the first row are blue but the cells in the second and third rows are white and the triangle is still sitting in the row header of the first row.  I expected it to be in the row header of the third row.

I tried to select all cells of all rows using the line that has been commented-out in the second loop of the code below but that didn't solve my problem.

Any thoughts on how to fix this (without making the DataGridView DataBound)?

Thanks.

public void                     displayMeasurements(List<clsMeasurement> L_Msrmt)
{
     DGV.Rows.Clear();
     foreach (clsMeasurement Msrmt in L_Msrmt)
     {
          int row = DGV.Rows.Add();

          DGV.Rows[row].Cells["col_x"].Value = Msrmt.x;
          DGV.Rows[row].Cells["col_y"].Value = Msrmt.y;
          DGV.Rows[row].Cells["col_x"].Value = Msrmt.y;
          DGV.Rows[row].Tag                           = Msrmt;
     }

     System.Diagnostics.Trace.WriteLine("before = " + DGV.SelectedRows.Count.ToString());
     DGV.ClearSelection();
     foreach (DataGridViewRow r in DGV.Rows)
     {
          r.Selected = true;
          //foreach (DataGridViewCell c in r.Cells) c.Selected = true;
     }
     System.Diagnostics.Trace.WriteLine("after = " + DGV.SelectedRows.Count.ToString());
}
Comment
Watch Question

Software Architect in .Net
CERTIFIED EXPERT
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
Roland,

   Odd stuff.  I have tried this on a Windows XP machine and a Windows 7 machine and on both of them I am getting the same results - only the cells of the first row have blue backgrounds.

   Below are the settings from the [UserControl].Designer.cs file.

   Thanks for the feedback.

//
// DGV
//
this.DGV.AllowUserToAddRows = false;
this.DGV.AllowUserToDeleteRows = false;
this.DGV.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.DGV.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.DGV.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.col_modfile,
this.col_Angle,
this.col_RMS_fitError});
this.DGV.ContextMenuStrip = this.contextMenuStrip1;
this.DGV.Location = new System.Drawing.Point(3, 3);
this.DGV.Name = "DGV";
this.DGV.Size = new System.Drawing.Size(732, 376);
this.DGV.TabIndex = 0;
this.DGV.CellValidated += new System.Windows.Forms.DataGridViewCellEventHandler(this.DGV_CellValidated);
this.DGV.CellValidating += new System.Windows.Forms.DataGridViewCellValidatingEventHandler(this.DGV_CellValidating);
Luis PérezSoftware Architect in .Net
CERTIFIED EXPERT

Commented:
Same results even applying all your properties to my grid. All rows are selected well. Sorry, I don't know what to do more.
CERTIFIED EXPERT
Top Expert 2015

Commented:
The MultiSelect property of the grid should be True in order to be able to select in more than one row.

And instead of looping through the cells, simply call the SelectAll method of the grid.

Author

Commented:
Thanks for the feedback.

The MultiSelect property is set to true when I look at the Property page for the DataGridView (i.e., in the MSVS 2010 Designer).  I suppose that the value of the MultiSelect proeprty does not appear in the Designer.cs file because 'true' is the default value for the MultiSelect property.  Similarly, the Enabled property is true in the Property page but it does not appear in Designer.cs.

Actually, I'm not looping through the cells.  I tried doing so at one point but that didn't help matters.

James - does the example code above work for you like it does for Roland?
CERTIFIED EXPERT
Top Expert 2015

Commented:
You are right, default values do not need to be set and thus are not defined in Designer.cs.

Have you tried SelectAll?

Have you search your code in case the MultiSelect property is changed in the code somewhere?

Sorry, I do not have any unbound DataGridView in my environment right now and do not have time to set up a test.

Author

Commented:
Thanks for all the help.  The issue has turned out to not be with the code that I originally submitted at all but with the way that I was using it.  Since Roland Deschain confirmed that the code was working in his initial replies I'm going to award the points to him.

Below are the details of what was going on.

The displayMeasurements(List<clsMeasurement> L_Msrmt) routine shown in my first post resides in a UserControl, UC_Bar.  An instance of UC_Bar sits on a Form that was opened using the following code:

frmFoo f = new frmFoo();
f.Initialize(L_Measurements);   // L_Measurements is of type List<clsMeasurement>
f.ShowDialog();

The Initialize(...) routine of frmFoo calls UC_Bar's displayMeasurements(...) routine (i.e., the one shown in my first post) which I thought would lead to all rows being selected.  Apparently calling ShowDialog() undid the selection of all except the first row.

To fix the issue I did a few things.  First, I got rid of the Initialize(...) routine altogether and added a public List<clsMeasurements> named myMeasurements to frmFoo.  This allowed the above code to be replaced with the following:

frmFoo f = new frmFoo();
f.myMeasurements = L_Measurements;
f.ShowDialog();

I also added a 'Load' EventHandler to frmFoo which initializes the instance of UC_Bar that sits on frmFoo:

private void frmFoo_Load(object sender, EventArgs e)
{
   uC_Bar.displayMeasurements(myMeasurements);
}

Author

Commented:
I very much appreciated Roland's effort to test the code snippet that I submitted - it was very useful confirmation that forced me to find the source of the problem which happened to not be in the code that I submitted at all.  Thanks for the help.
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.