2008-12-05 7 views
0

J'essaie de trier les colonnes d'une grille de données de A à Z, le code ci-dessous fonctionne à part que je reçois une colonne commençant par 'c' entre le «A» (par exemple, a, a, a, a, c, a, a, b, b, b), cela se produit la première fois que je lance le code. Si j'utilise ensuite columnNames.Reverse(); (Z à A), puis réexécutez columnNames.Sort() (A à Z), il trie correctement. Pourquoi cela serait-il?Tri d'une colonne DataGrid, j'ai le code et ça fonctionne

List<string> columnNames = new List<string>(); 
foreach (DataGridViewColumn col in dataGridView1.Columns) 
columnNames.Add(col.HeaderText); 
columnNames.Sort(); 
foreach (DataGridViewColumn col in dataGridView1.Columns) 
    col.DisplayIndex = columnNames.IndexOf(col.HeaderText); 

Merci

Répondre

1

Dans votre exemple ("(a, a, a, a, c, a, a, b, b, b)"), les noms de colonnes ne sont pas uniques. Ainsi, dans la liste des noms triés, le (premier) index de "a" sera 0, le premier (index) de "b" sera 5, et le (premier) index de "c" sera 8.

Ainsi, lorsque vous parcourez les colonnes, vous définissez à plusieurs reprises des colonnes avec le texte «a» pour avoir l'index «0». La deuxième fois que vous faites cela, la première colonne dans cette position sera déplacée pour faire de la place. Le résultat ressemble plus à des cartes mélangées qu'à un tri, et l'ordre final dépend de l'ordre d'origine. C'est pourquoi le tri fonctionne bien la deuxième fois - pendant votre premier passage, vous arrangez les éléments "assez près" que la deuxième tentative réussit.

Qu'en est-il de quelque chose comme ce qui suit à la place? Il attribuera les indices de manière unique, et il sera également plus efficace. (Chaque appel à IndexOf est O (N), donc votre code d'origine est O (N^2) - c'est juste O (N log N), au moins en supposant que la collection de colonnes ne soit pas trop réorganisée

List<DataGridViewColumn> columns = new List<DataGridViewColumn>(dataGridView1.Columns); 
columns.Sort(delegate(DataGridViewColumn a, DataGridViewColumn b) { 
       return String.Compare(a.HeaderText, b.HeaderText); } 
int n = 0; 
foreach(DataGridViewColumn col in columns) 
    col.DisplayIndex = n++; 
Questions connexes