Reputation: 516
TL;DR: When changing DataMember tables in a DataSet bound to a DataGridView with NotSortable column SortMode and ColumnSelect SelectionMode, an InvalidOperationException is thrown because the SortMode appears as "Automatic".
I have implemented an Excel input feature into my app, and I'm using the ExcelDataReader package from NuGet to do so. This is reading my Excel files and converting them into DataSet as expected.
However, when I tried to bind that DataSet to a DataGridView, with the intention of allowing the user to "select" what cells/columns/rows to use, I received the error the following InvalidOperationException when enabling Column selection mode:
Column's SortMode cannot be set to Automatic while the DataGridView control's SelectionMode is set to ColumnHeaderSelect.
This was solved using this answer on another question, which works as expected on initial bind.
However, the Excel spreadsheet may have multiple Worksheets, so I have displayed them using a ComboSelectBox -- and on SelectionChangeCommitted, I am changing the DataGridView's DataMember to the index of the selected Worksheet.
On this change I am still getting the InvalidOperationException above, even though I am repeating the exact same code as in the initial bind -- that is working correctly.
So question is, how can I stop the SortMode from apparently being reset to Automatic or get the same code that's working for the initial Bind to work on the DataMember change.
Thanks :)
ExcelForm.cs
// This works fine on initial Bind, no errors
private void PrepareUI()
{
// DataGridView dataGridContents
dataGridContents.DataSource = _contents;
dataGridContents.DataMember = _contents.Tables[0].TableName;
dataGridContents.SetColumnSortMode(DataGridViewColumnSortMode.NotSortable);
dataGridContents.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect;
DataTable worksheets = GetWorksheetValues(_contents);
comboWorksheet.DataSource = worksheets;
comboWorksheet.ValueMember = "index";
comboWorksheet.DisplayMember = "name";
}
// On SelectionChangeCommitted, same code -- but throws an InvalidOperationException
private void comboWorksheet_SelectionChanged(object sender, EventArgs e)
{
dataGridContents.DataMember = _contents.Tables[int.Parse(((ComboBox)sender).SelectedValue.ToString())].TableName;
dataGridContents.SetColumnSortMode(DataGridViewColumnSortMode.NotSortable);
dataGridContents.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect;
}
DataGridViewExtensions.cs
static class DataGridViewExtensions
{
public static void SetColumnSortMode(this DataGridView dataGridView, DataGridViewColumnSortMode sortMode = DataGridViewColumnSortMode.NotSortable)
{
foreach (DataGridViewColumn c in dataGridView.Columns)
{
c.SortMode = sortMode;
}
}
}
Upvotes: 1
Views: 1996
Reputation: 516
Solved, in my SelectionChangeCommitted eventHandler I simply changed the DataGridView SelectionMode back to RowHeaderSelect before changing the DataMember, and then my DataMemberChanged eventHandler changes it back again to ColumnHeaderSelect.
private void comboWorksheet_SelectionChanged(object sender, EventArgs e)
{
dataGridContents.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
dataGridContents.DataMember = _contents.Tables[int.Parse(((ComboBox)sender).SelectedValue.ToString())].TableName;
}
private void dataGridContents_DataMemberChanged(object sender, EventArgs e)
{
dataGridContents.SetColumnSortMode(DataGridViewColumnSortMode.NotSortable);
dataGridContents.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect;
}
I feel like this is messy, but it works.
Upvotes: 0