如上所述here,只要数据源的内容发生更改,或者DataBindingComplete
等属性发生更改,就会触发DataGridView的DataSource
事件。这导致该方法被多次调用
我目前正在使用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
事件。
答案 0 :(得分:2)
最简单的方法就是执行一次代码:
在表单中添加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,但它足够接近。
当然,事件本来是一个近乎理想的解决方案,但除了AutoGenerateColumnChanged
之外,几乎没有任何事情可以处理列http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview_events(v=vs.110).aspx的成功自动生成,但这不是我们需要的。< / p>
虽然可以使用ColumnAdded - 它可能只会执行自动生成列的一次,实际的实现可能会变得过大,甚至比已经提到的方法更不直接。
如果您有时间和愿望可以创建自己的DataGridView派生类,请从表单中取出Boolean isDataGridFormatted
并在自定义DataGridView中实现所有初始化(或事件挂钩)。
答案 1 :(得分:0)
是的,您可以使用DataSourceChanged
事件,但请注意,只有在更改数据源时才会发生此事件。此外,DataBindingComplete
通过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
整个事情发生的原因是你在DataMember
中没有设置dataGridView
属性。只有当您想要设置为DataSource
dataGridView
的数据库中的特定表时,才可以设置它。其他方式 - 抛出异常。