DataGridView DataBindingComplete事件的替代方案

时间:2014-06-20 14:45:37

标签: c# winforms datagridview

如上所述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事件。

2 个答案:

答案 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的数据库中的特定表时,才可以设置它。其他方式 - 抛出异常。