代码项目的文章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());
非常感谢,因为这已经引起了相当大的我悲伤。知道我需要做什么,并尝试用单一参数进行排序,但将两者结合是问题所在。这是一个很大的帮助!我确实有一个空字符串,即“”作为第一个条目。通过这种方法,空单元在数字和字母之间的中间结束。有没有一种方法可以进一步调整,使空单元格成为第一个单元格中的第一个条目,然后是数字,然后是字母?我希望这是数据网格的默认条目。 –
我想我已经设法自己排除这个 –
如果(xStr ==“”) { return 0;}如果(xStr ==“”)开始的行后面插入以下内容: } –