2008-10-22 27 views
0

我插入在一個DataGridView列編程(即,不束縛於任何數據表/數據庫)如下:爲什麼Columns.Insert不更新DataGridView(C#)中的DisplayIndex?

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 

另外,我的網格可以動態增加列數。我想將它擴大成塊,因此每個插入不需要列分配(和相關的初始化)。然後通過從末端抓取未使用的列,將其插入到所需的位置並使其可見,從而添加每個「新」列。

回答

2

我懷疑這是因爲DataGridView中列的順序不一定指示顯示順序,雖然沒有明確指定默認情況下列的順序決定了DisplayIndex屬性值。這就是DisplayIndex屬性的原因,因此您可以在不執行插入的情況下將列添加到集合中 - 您只需指定DisplayIndex值,並對具有相同或更大DisplayIndex的所有內容進行級聯更新。從您的示例中可以看出,插入的列也正在接收第一個跳過的DisplayIndex值。

a question/answer我發現:

改變的DisplayIndex將導致舊 的DisplayIndex和新的DisplayIndex 之間 所有列移位。

與幾乎所有的收藏(LinkedList除外)一樣,總是最好添加到收藏集than insert into。你所看到的行爲反映了這一規則。

+0

此外,由於底層Columns數據結構的分離以及DisplayIndex用法的顯示順序,因此不需要通過在塊中添加列來進行優化,這可能會使事情變得複雜。 – cfeduke 2008-10-22 21:59:02

0

感謝cfeduke的優秀建議。我懷疑Insert會比較慢,但是提供的鏈接讓我明白如何慢一些。

這帶來了如何在DataGridView上動態插入和刪除列的問題。看起來理想的設計是使用AddAddRange添加大量列,然後從不真正刪除它們。然後,您可以通過將Visible屬性設置爲false來模擬刪除。你可以通過抓取一個不可見的列來插入一個列,將其設置爲DisplayIndex並使其可見。

不過,我懷疑會有地雷來避免這種方法。最重要的是你不能再以簡單的方式索引你的數據。也就是說,m_DGV.Columns[i]m_DGV.Rows[n].Cells[i]將不會正確映射。我想你可以創建一個Map/Dictionary來維護一個外部的直觀映射。

由於我的應用程序(按照當前設計)需要頻繁地插入和移除列,因此可能值得。任何人有任何建議?

2

我有幾個想法。

  1. 如何通過唯一名稱尋址列而不是集合中的索引?他們可能還沒有一個名字,但如果你給了他們一個名字,那麼你可以跟蹤誰是誰。

  2. 可以使用GetFirstColumnGetNextColumnGetPreviousColumnDataGridViewColumnCollection類的GetLastColumn方法,它在顯示順序的工作,而不是集合中的順序。您也可以使用for循環和m_DGV.Columns[i]迭代集合,直到找到所需的。

  3. 創建一個繼承的DataGridViewDataGridViewColumnCollectionDataGridView只是被覆蓋以使用您的新集合類。你的新DataGridViewColumnCollection將包括一個方法來解決顯示索引收集,大概是通過迭代收集,直到你找到你想要的(見#2)。或者你可以保存一本字典,並保持它爲大量的列更新。

    我懷疑保持字典的性能提高了,因爲每次列移動時,都必須重寫整個事物。無論如何,迭代遍歷都是O(n),除非你正在談論數百個列的異步操作,否則你可能沒問題。

    您或許也可以覆蓋this[]運營商,假設它並沒有搞砸DataGridView

想法#1可能是最容易實現的,但不一定是最漂亮的。想法#2的作品,你可以把它放在一個功能DataGridViewColumn GetColumnByDisplayIndex(int Index)。想法#3是可愛的,當然也是最封裝的方法,但不是微不足道的。