DataGridView DataBindingComplete事件的替代方案

如此处所述,只要数据源的内容发生更改,或者DataSource等属性发生更改,就会触发DataGridView的DataBindingComplete事件。 这导致该方法被多次调用。
我目前正在使用DataBindingComplete事件对我的表单进行一些可视化格式化。 例如,我将第一列(第0列)中的文本显示为行标题,然后隐藏该列(请参阅下面的代码)。

 private void grdComponents_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e) { foreach (DataGridViewRow row in grdComponents.Rows) { row.HeaderCell.Value = row.Cells[0].Value.ToString(); } grdComponents.Columns[0].Visible = false; // do more stuff... } 

没有必要多次执行此代码,我希望将其放入可能发生的地方。 不幸的是,当我将片段添加到我的表单的Load方法的末尾时(在我设置DataGridView的DataSource之后),它也没有用,也没有在DataSourceChanged事件中工作。

最简单的方法就是执行一次这段代码:

在表单中添加类似Boolean isDataGridFormatted的标志。

并检查它

 private void grdComponents_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e) { if (this.isDataGridFormatted ) return; foreach (DataGridViewRow row in grdComponents.Rows) { row.HeaderCell.Value = row.Cells[0].Value.ToString(); } grdComponents.Columns[0].Visible = false; // do more stuff... this.isDataGridFormatted = false; } 

更好的方法是在表单构造期间准备DataGridView。 据我所知,您的列在程序过程中不会改变,但您不想手动初始化所​​有内容。 您可以在初始化期间加载一些虚拟的单项(一行)数据:

 private void Initialize_DataGridView() { // Add dummy data to generate the columns this.dataGridView_Items.DataContext = new Item[]{ new Item {Id = 5, Value = 6}}; // Make your formatting foreach (DataGridViewRow row in grdComponents.Rows) { row.HeaderCell.Value = row.Cells[0].Value.ToString(); } grdComponents.Columns[0].Visible = false; // Reset the dummy data this.dataGridView_Items.DataContext = null; // Or new Item[]{}; } ... public MyForm() { Initialize(); this.Initialize_DataGridView(); } 

我不确定这样的代码是否适用于dataGridView,但它足够接近。

当然,一个事件本来是一个近乎理想的解决方案,但几乎没有任何成功处理列的自动生成http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview_events(v=vs。 110).aspx除了AutoGenerateColumnChanged但这不是我们需要的。

虽然可以使用ColumnAdded – 它可能只执行自动生成列的一次,实际的实现可能变得过度,并且甚至比已经提到的方法更不直接。

如果您有时间和愿望可以创建自己的DataGridView派生类,请从表单中获取Boolean isDataGridFormatted并在自定义DataGridView中实现所有初始化(或事件挂钩)。

是的,您可以使用DataSourceChanged事件,但要注意,它仅在数据源发生更改时才会发生。 此外, DataBindingComplete通过e.ListChangedType为您提供信息发生的e.ListChangedType

 Reset = 0,// Much of the list has changed. Any listening controls should refresh all their data from the list. ItemAdded = 1,// An item added to the list ItemDeleted = 2,// An item deleted from the list. ItemMoved = 3,// An item moved within the list. ItemChanged = 4,// An item changed in the list. PropertyDescriptorAdded = 5,// A System.ComponentModel.PropertyDescriptor was added, which changed the schema. PropertyDescriptorDeleted = 6,// A System.ComponentModel.PropertyDescriptor was deleted, which changed the schema. PropertyDescriptorChanged = 7// A System.ComponentModel.PropertyDescriptor was changed, which changed the schema. 

根据这个答案: https : //social.msdn.microsoft.com/forums/windows/en-us/50c4f46d-c3b8-4da7-b08f-a751dca12afd/databindingcomplete-event-is-been-called-twice整个事情发生了因为您没有在dataGridView设置DataMember属性。 只有当您想要从数据库设置特定表时才能设置它,该数据库被设置为dataGridViewDataSource 。 其他方式 – 抛出exception。