概要
BindingモードのDataGridView.DataSourceに列を追加すると、DataGridViewにも列が追加されて便利だが、SelectionModeがColumnHeaderSelectまたはFullColumnSelectな時は工夫が必要。
問題
データバインディングと複数列選択を共存させようとするとInvalidOperationExceptionを投げる。これはバインディングが自動生成する列のSortModeの規定値がAutomaticになっているため。
Form.cs
public partial class Form1 : Form
{
private DataTable m_Table;
public Form1()
{
InitializeComponent();
this.dataGridView1.AutoGenerateColumns = true;
this.dataGridView1.MultiSelect = true;
this.dataGridView1.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect;
m_Table = new DataTable();
m_Table.Columns.Add();
this.dataGridView1.DataSource = new BindingSource().DataSource = m_Table;
}
}
output
DataGridView control's SelectionMode cannot be set to ColumnHeaderSelect while it has a column with SortMode set to DataGridViewColumnSortMode.Automatic.
解決
DataGridViewに列が追加されるたびにSortModeをProgrammaticまたはNotSortableに変更すれば良い。
Form.cs
public partial class Form1 : Form
{
private DataTable m_Table;
public Form1()
{
InitializeComponent();
this.dataGridView1.AutoGenerateColumns = true;
this.dataGridView1.MultiSelect = true;
this.dataGridView1.SelectionMode = DataGridViewSelectionMode.ColumnHeaderSelect;
this.dataGridView1.Columns.CollectionChanged += Columns_CollectionChanged;
m_Table = new DataTable();
m_Table.Columns.Add();
this.dataGridView1.DataSource = new BindingSource().DataSource = m_Table;
}
void Columns_CollectionChanged(object sender, CollectionChangeEventArgs e)
{
if (e.Action == CollectionChangeAction.Add)
{
var column = e.Element as DataGridViewColumn;
column.SortMode = DataGridViewColumnSortMode.Programmatic;
}
}
}