代码之家  ›  专栏  ›  技术社区  ›  e-holder

为什么Columns.Insert不更新DataGridView(C#)中的DisplayIndex?

  •  0
  • e-holder  · 技术社区  · 18 年前

    我以编程方式(即不绑定到任何数据表/数据库)在DataGridView中插入一列,如下所示:

    int lastIndex = m_DGV.Columns.Count - 1;  // Count = 4 in this case
    DataGridViewTextBoxColumn col = (DataGridViewTextBoxColumn)m_DGV.Columns[lastIndex];
    m_DGV.Columns.RemoveAt(lastIndex);
    m_DGV.Columns.Insert(insertIndex, col);  // insertIndex = 2
    

    我发现有时使用这种方法时,我的列在视觉上是无序的。解决方法是在之后手动设置列的DisplayIndex属性。添加这段代码“修复了它”,但我不明白它为什么会这样。

    Console.Write(m_DGV.Columns[0].DisplayIndex); // Has value of 0
    Console.Write(m_DGV.Columns[1].DisplayIndex); // Has value of 1
    Console.Write(m_DGV.Columns[2].DisplayIndex); // Has value of 3
    Console.Write(m_DGV.Columns[3].DisplayIndex); // Has value of 2
    col.DisplayIndex = insertIndex;
    Console.Write(m_DGV.Columns[0].DisplayIndex); // Has value of 0
    Console.Write(m_DGV.Columns[1].DisplayIndex); // Has value of 1
    Console.Write(m_DGV.Columns[2].DisplayIndex); // Has value of 2
    Console.Write(m_DGV.Columns[3].DisplayIndex); // Has value of 3
    

    3 回复  |  直到 18 年前
        1
  •  2
  •   cfeduke    18 年前

    我怀疑这是因为DataGridView中列的顺序不一定决定显示顺序,尽管默认情况下没有显式指定列的顺序决定DisplayIndex属性值。这就是为什么有一个DisplayIndex属性,所以您可以在不执行插入的情况下向集合中添加列-您只需要指定DisplayIndex值,并且对具有相等或更大DisplayIndex的所有内容进行级联更新。从您的示例中可以看出,插入的列还接收到第一个跳过的DisplayIndex值。

    从…起 a question/answer

    更改DisplayIndex将导致 所有列之间的旧 DisplayIndex和新的DisplayIndex

    than insert into 收藏。你所看到的行为就是这一规则的反映。

        2
  •  2
  •   lc.    17 年前

    我有几个想法。

    1. 你可以使用 GetFirstColumn , GetNextColumn , GetPreviousColumn GetLastColumn 调查方法 DataGridViewColumnCollection 类,该类处理显示顺序,而不是集合中的顺序。您还可以使用for循环和 m_DGV.Columns[i] 直到你找到你想要的。

    2. 创建一个继承的 DataGridView DataGridViewColumnCollection DataGridViewColumnCollection

      我怀疑保留字典的性能提高,因为每次一列移动时,您都必须重写整个内容。无论如何,遍历都是O(n),除非您讨论的是具有数百列的异步操作,否则您可能不会有问题。

      您可能可以覆盖 this[] 接线员也一样,假设它没有搞砸 .

    想法1可能是最容易实现的,但不一定是最漂亮的。想法#2起作用,你可以把它放在一个函数中 DataGridViewColumn GetColumnByDisplayIndex(int Index)

        3
  •  0
  •   e-holder    17 年前

    感谢cfeduke的宝贵建议。我怀疑 Insert 会更慢,但提供的链接让我明白了速度到底有多慢。

    这就提出了如何在DataGridView上高效地动态插入和删除列的问题。看起来理想的设计应该是使用 Add 或 AddRange Visible 属性设置为false。您可以通过抓取一个不可见的列,设置其 DisplayIndex

    然而,我怀疑用这种方法会有地雷要避免。最重要的是,您不能再以直接的方式为数据编制索引。就是, m_DGV.Columns[i] 和 m_DGV.Rows[n].Cells[i] 将无法正确映射。我想您可以创建一个地图/字典来维护外部直观的地图。

    推荐文章