title: DataGridView Changing AutoSizeRowsMode Throws Exception
body: <p>If a dgv is currently has <code>AutoSizeRowsMode = DisplayedCells</code>, then setting to <code>None</code> causes an exception.</p>
  
  <p>Below is the code to reproduce the issue. To cause the exception to occur, simply click on one of the column headers. The exception will happen even if some of the rows are visible. However, if the <code>Form</code> is resized large enough then the exception stops happening. Tested using <code>.NET35</code> <code>.NET40</code> and <code>.NET45.</code></p>
  
  <pre><code>public class MyForm : Form {
      Button btn = new Button { Text = "Button" };
  
      public MyForm() {
          Controls.Add(btn);
          btn.Click += btn_Click;
      }
  
      void btn_Click(object sender, EventArgs e) {
          DataGridView dgv = new DataGridView { Dock = DockStyle.Fill };
          dgv.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
          dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
          dgv.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells; // &lt;---- this is required to cause the exception
          dgv.ColumnHeadersDefaultCellStyle.Font = new System.Drawing.Font(SystemFonts.MenuFont.FontFamily, 14f, FontStyle.Bold);
  
          // The underlying data source doesn't matter, exception happens in both cases
          //dgv.Columns.Add("Column1", "Column1");
          //dgv.Columns.Add("Column2", "Column2");
          //dgv.Columns.Add("Column3", "Column3");
  
          DataTable table = new DataTable();
          table.Columns.Add("Column1");
          table.Columns.Add("Column2");
          table.Columns.Add("Column3");
          for (int i = 0; i &lt; 10; i++) {
              table.Rows.Add(i, i, i);
              //dgv.Rows.Add(i, i, i);
          }
          dgv.DataSource = table;
          Form f = new Form();
          f.Controls.Add(dgv);
          f.Size = new System.Drawing.Size(400, 90); // just enough so only the headers are visible
          f.Show();
  
          dgv.MouseDown += dgv_MouseDown;
      }
  
      void dgv_MouseDown(object sender, MouseEventArgs e) {
          DataGridView dgv = (DataGridView) sender;
  
          // using reflection, the Exception occurs on rowIndex == 1
          //int index = 0;
          //Type ty = typeof(DataGridViewRow);
          //var pi = ty.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic).Cast&lt;PropertyInfo&gt;().Where(p =&gt; p.Name == "ThicknessInternal").FirstOrDefault();
          //var pi2 = ty.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic).Cast&lt;PropertyInfo&gt;().Where(p =&gt; p.Name == "CachedThickness").FirstOrDefault();
          //for (index = dgv.Rows.GetFirstRow(DataGridViewElementStates.Visible); index != -1; index =  dgv.Rows.GetNextRow(index, DataGridViewElementStates.Visible)) {
          //  DataGridViewRow dataGridViewRow = dgv.Rows.SharedRow(index);
          //  object val1 = pi.GetValue(dataGridViewRow);
          //  object val2 = pi.GetValue(dataGridViewRow);
          //  pi.SetValue(dataGridViewRow, val2);
          //}
  
          dgv.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None; // &lt;------- Exception here
      }
  
  }
  </code></pre>
  
  <p>Here is the exception stack trace:</p>
  
  <pre><code>   at System.Windows.Forms.DataGridViewRowCollection.GetRowState(Int32 rowIndex)
     at System.Windows.Forms.DataGridView.OnRowGlobalAutoSize(Int32 rowIndex)
     at System.Windows.Forms.DataGridView.RestoreRowsCachedThickness()
     at System.Windows.Forms.DataGridView.OnAutoSizeRowsModeChanged(DataGridViewAutoSizeModeEventArgs e)
     at Program.MyForm.dgv_MouseDown(Object sender, MouseEventArgs e) in c:\temp\...\Program.cs:line 2483
  </code></pre>
  
  <p>Looking at the source code for <code>DataGridView</code> on <code>MSDN</code>: <a href="http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/DataGridViewMethods.cs,237455f3980aebd9" rel="nofollow">http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/DataGridViewMethods.cs,237455f3980aebd9</a></p>
  
  <p>The <code>RestoreRowsCachedThickness</code> loops through each row and sets: <code>dataGridViewRow.ThicknessInternal = dataGridViewRow.CachedThickness;</code></p>
  
  <p>The <code>DataGridViewBand.ThicknessInternal</code> property doesn't check to see if the values are actually different, it always fires the <code>OnBandThicknessChanged</code> event.</p>
  
  <p>That triggers an event which calls a couple of other methods, eventually getting to the line:</p>
  
  <pre><code>    private void OnRowGlobalAutoSize(int rowIndex)
      {
          DataGridViewElementStates rowState = this.Rows.GetRowState(rowIndex);
  //...
      }
  </code></pre>
  
  <p>It is strange that the <code>RowCollection</code> is throwing an index out of bounds exception.</p>
  
  <p>Is there a sensible way to handle this exception (bug?) besides wrapping it in a <code>try-catch</code> statement?</p>