我目前的情况如下:我有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,事件处理)更为基础。欢迎任何回答的尝试。
答案 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;
}