【问题标题】:Alternative to DataGridView DataBindingComplete EventDataGridView DataBindingComplete 事件的替代方案
【发布时间】:2014-06-20 14:45:37
【问题描述】:

here 所述,只要数据源的内容发生更改,或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...
    }

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

【问题讨论】:

  • This post 帖子解决了我的类似问题。我将 DataMember 属性设置为 DataSource 中使用的表名,并且事件现在只触发一次。请注意,如果 DataSource 仅包含一个表,则不需要 DataMember 属性,但我使用它来避免多次触发事件。参考:[MSDN](msdn.microsoft.com/en-us/library/…)

标签: c# winforms datagridview


【解决方案1】:

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

在您的表单中添加类似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,但这不是我们需要的。

虽然可以使用ColumnAdded - 对于自动生成的列,它可能只执行一次,但实际实现可能会变得矫枉过正,甚至比已经提到的方法更不直接。

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

【讨论】:

  • 感谢您的回答。我之前考虑过这一点,希望还有一个我可以使用的事件而不是一个标志(它有点 hack-y)。
  • 这很有趣。我添加了标志,导致我的格式不显示... DataBindingComplete 方法被调用两次:标记的代码第一次执行但不是第二次,然后没有显示第一个方法调用的任何更改.
  • 您是否尝试过单步执行您的代码以查看它何时发生?也许第一次是在 Form.Initialize 方法内?第二个是您实际设置数据的时间?或者你以某种方式设置了两次?
  • 在绑定处理程序中设置断点,在 Form.Initialize 之前和之后。并查看是否会调用绑定处理程序。
【解决方案2】:

是的,您可以使用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 整个事情的发生是因为您的dataGridView 中没有设置DataMember 属性。只有当您想从数据库中设置特定表时才能设置它,该表设置为DataSourcedataGridView。其他方式 - 引发异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 2023-04-05
    • 1970-01-01
    相关资源
    最近更新 更多