2016-12-20 48 views
0

我有一个列允许用户输入可能包含数字的字符串的数据网格。我已经做了编程排序的列和另一个自动排序的列。 我已查看过有关此网站和其他网站的所有可用信息,但没有找到任何可行的信息,或者在某些情况下我能够知道如何实施。 许多解决方案都使用Icomparer,但很少有专门用于datagridview的解决方案。 这是执行datagridview1.Sort(Column1,ListSortDirection.Ascending)后列数据的示例;自然排序为Datgridview

1 
140 
2b 
40 
70 
7a 
9 
aa 
aa30 
aa5 
bc 
de 

我已经介绍了MyDatagridHelper类和相关代码使用本网站的解决方案: C#: Custom sort of DataGridView, 但可惜它提供了以下结果

aa 
bc 
de 
aa30 
2b 
7a 
70 
1 
40 
140 
9 
aa5 

所有其他解决方案并不是专门针对datagridview的。我是自学成才,对编码相对较新,所以我无法理解其中的代码。我尽可能地尝试找到共同点,并剪切和粘贴,但无济于事。 一些例子我想表明的承诺,可能做的工作是: https://www.codeproject.com/articles/22517/natural-sort-comparerNatural Sort Order in C#

我需要有效上如何实现这些或任何其他的解决方案,可能做的工作是有帮助。 为简单起见,我没有列入第二列,因为它与问题无关。 感谢

回答

0

代码项目的文章22517,你链接到在那里,你所需要的逻辑,它只是通过创建System.Collections.IComparer的实现,而不是System.Collections.Generic.Comparer

所以,如果你需要一些调整为与DataGridView使用自己创建一个新的类在你的项目是这样的:

public class NaturalSortComparer : System.Collections.IComparer { 

    private System.Collections.Generic.Dictionary<string, string[]> table; 

    public NaturalSortComparer() { 
     table = new System.Collections.Generic.Dictionary<string, string[]>(); 
    } 

    public void Dispose() { 
     table.Clear(); 
     table = null; 
    } 

    public int Compare(object x, object y) { 
     System.Windows.Forms.DataGridViewRow DataGridViewRow1 = (System.Windows.Forms.DataGridViewRow)x; 
     System.Windows.Forms.DataGridViewRow DataGridViewRow2 = (System.Windows.Forms.DataGridViewRow)y; 

     string xStr = DataGridViewRow1.Cells["Column1"].Value.ToString(); 
     string yStr = DataGridViewRow2.Cells["Column1"].Value.ToString(); 


     if (xStr == yStr) { 
      return 0; 
     } 
     string[] x1, y1; 
     if (!table.TryGetValue(xStr, out x1)) { 
      x1 = System.Text.RegularExpressions.Regex.Split(xStr.Replace(" ", ""), "([0-9]+)"); 
      table.Add(xStr, x1); 
     } 
     if (!table.TryGetValue(yStr, out y1)) { 
      y1 = System.Text.RegularExpressions.Regex.Split(yStr.Replace(" ", ""), "([0-9]+)"); 
      table.Add(yStr, y1); 
     } 

     for (int i = 0; i < x1.Length && i < y1.Length; i++) { 
      if (x1[i] != y1[i]) { 
       return PartCompare(x1[i], y1[i]); 
      } 
     } 
     if (y1.Length > x1.Length) { 
      return 1; 
     } else if (x1.Length > y1.Length) { 
      return -1; 
     } else { 
      return 0; 
     } 
    } 

    private static int PartCompare(string left, string right) { 
     int x, y; 
     if (!int.TryParse(left, out x)) { 
      return left.CompareTo(right); 
     } 

     if (!int.TryParse(right, out y)) { 
      return left.CompareTo(right); 
     } 

     return x.CompareTo(y); 
    } 
} 

你可以在这里看到我硬编码它使用了一个名为“列1”按你的例子​​列,但你可以改变这是更具活力。

当你再排序网格,你可以通过这个类,你刚刚创建,像这样的一个新实例:

dataGridView1.Sort(new NaturalSortComparer()); 
+0

非常感谢,因为这已经引起了相当大的我悲伤。知道我需要做什么,并尝试用单一参数进行排序,但将两者结合是问题所在。这是一个很大的帮助!我确实有一个空字符串,即“”作为第一个条目。通过这种方法,空单元在数字和字母之间的中间结束。有没有一种方法可以进一步调整,使空单元格成为第一个单元格中的第一个条目,然后是数字,然后是字母?我希望这是数据网格的默认条目。 –

+0

我想我已经设法自己排除这个 –

+0

如果(xStr ==“”) { return 0;}如果(xStr ==“”)开始的行后面插入以下内容: } –