C#如何绕过DataGridView_DataBindingComplete事件

时间:2016-01-20 08:00:46

标签: c# .net winforms datagridview

我目前的情况如下:我有3个datagridviews,我可以过滤它们(通过bindingsource.filter),也可以从一个datagridview移动列。执行此操作的代码:

//Move from third datagrid to first
private void moveToFirstGridToolStripMenuItem1_Click(object sender, EventArgs e)
    {
        dataGridView3.Columns[currentColumnIndex].Visible = false;
        dataGridView1.Columns[currentColumnIndex].Visible = true;
        currentColumnIndex = -5;
    }

这是有效的,因为所有三个数据网格都具有与数据源相同的数据表,具有此表的所有列,并且我只是随时控制显示的内容。  这3个datagridviews,每个都有一个单独的绑定源。但是,所有三个绑定源都从同一数据表中获取数据。我还使用以下逻辑控制用户看到的内容:在第一个网格上显示10个第一列,在第二个网格上显示下一个10,在第三个网格上显示下一个10。

我遇到了一个小问题,只要第一个数据网格中只有列,数据表的第一个列也会显示在第二个和第三个数据网格上,我不想要。通过这个问题:DataGridView shows columns that were set to non-visible我能够通过该答案处理数据绑定完成事件。对于所有3个datagrids,这是我当前的处理程序:

private void DataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
    {
DataGridView view = sender as DataGridView; 
        bool anyVisible = false;
        int max = 0, min = 0;
        if (view == this.dataGridView1)
        {
            min = 0;
            max = 10;
        }
        if (view == this.dataGridView2)
        {
            min = 10;
            max = 20;
        }
        if (view == this.dataGridView3)
        {
            min = 20;
            max = 30;
        }

        for (int i = 0; i < this.m_CurrentTable.Columns.Count; i++)
        {
            view.Columns[i].Visible = i >= min && i < max;
            anyVisible = anyVisible || view.Columns[i].Visible;
        }

        view.RowHeadersVisible = anyVisible;
        view.ScrollBars = anyVisible ? ScrollBars.Both : ScrollBars.None;
}

出现问题:如果我将一个列从datagrid 3移动到datagrid 1,然后尝试过滤,我希望它能像预期的那样工作。此代码不允许您这样做,因为例如我将第21列(第3个数据网格)移动到第一个,然后进行过滤,当为每个数据网格触发一次数据绑定完成事件时,第21列将移回到第三个数据网格。过滤工作正常,但列的位置被重置,我不想要。

基本上我的过滤器指定要显示的行,以及数据绑定完成事件列。我可以实现一个布尔值来检查是否有过滤器,然后避免这个事件,但这不是一个很好的解决方案,也会导致其他问题。

我想到的一种方法可能是我可以尝试将绑定源数据源重置为当前的datagrid数据源(在将列移动到它时已经更改),在数据绑定完成事件中。我仍然试图看看这是否有意义。也许可以使用的另一件事是datagridviewbindingcomplete事件args的e.listchangedtype,但我没有经验。

这显然是一个专门的问题,但它的一部分(datagridview,事件处理)更为基础。欢迎任何回答的尝试。

1 个答案:

答案 0 :(得分:1)

您需要维护一个列属于哪个数据网格视图的逻辑映射,而不是阻止事件,并在网格之间移动列时相应地更新它。

例如,像这样

private int[] columnViewIndex = Enumerable.Repeat(0, 10)
    .Concat(Enumerable.Repeat(1, 10))
    .Concat(Enumerable.Repeat(2, 10))
    .ToArray();

private void moveToFirstGridToolStripMenuItem1_Click(object sender, EventArgs e)
{
    dataGridView3.Columns[currentColumnIndex].Visible = false;
    dataGridView1.Columns[currentColumnIndex].Visible = true;
    columnViewIndex[currentColumnIndex] = 0; // 1, 2 in other move methods
    currentColumnIndex = -5;
}

private void DataGridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
    var view = sender as DataGridView;
    int viewIndex = view == this.dataGridView1 ? 0 : view == this.dataGridView2 ? 1 : 2;
    bool anyVisible = false;
    for (int i = 0; i < this.m_CurrentTable.Columns.Count; i++)
    {
        bool visible = i < columnViewIndex.Length && columnViewIndex[i] == viewIndex;
        view.Columns[i].Visible = visible;
        anyVisible = anyVisible || visible;
    }

    view.RowHeadersVisible = anyVisible;
    view.ScrollBars = anyVisible ? ScrollBars.Both : ScrollBars.None;
}