2008-09-18 44 views
4

我的DataView行事有趣,它按字母顺序排列事物,我需要它用数字排序。我已经浏览了网页上的所有内容,并发现了很多关于如何使用ICompare对其进行排序的想法,但没有什么可靠的。如何自然地将DataView与IComparable类似的排序

所以我的问题是

  1. 如何在一个数据视图实现ICompare(寻找代码在这里)。
  2. 如何正确解读包含实际字符串和充满数字(带逗号)的字符串的列。

我需要代码来帮助我解决这个问题。我对ICompare的想法或者如何在不同的场景中实现都有点失落,所以一个好的解释会很棒。

另外,请不要给我链接。我正在寻找这一个坚实的答案。

我使用的一些代码。

DataView dataView = (DataView)Session["kingdomData"]; 
    dataView.Sort = e.SortExpression + " " + ConvertSortDirectionToSql(e.SortDirection); 
    gvAllData.DataSource = dataView; 
    gvAllData.DataBind(); 



    private string ConvertSortDirectionToSql(SortDirection sortDirection) 
{ 
    string newSortDirection = String.Empty; 
    if (Session["SortDirection"] == null) 
    { 
     switch (sortDirection) 
     { 
      case SortDirection.Ascending: 
       newSortDirection = "ASC"; 
       break; 
      case SortDirection.Descending: 
       newSortDirection = "DESC"; 
       break; 
     } 
    } 
    else 
    { 
     newSortDirection = Session["SortDirection"].ToString(); 
     switch (newSortDirection) 
     { 
      case "ASC": 
       newSortDirection = "DESC"; 
       break; 
      case "DESC": 
       newSortDirection = "ASC"; 
       break; 
     } 
    } 
    Session["SortDirection"] = newSortDirection; 
    return newSortDirection; 
} 
+0

请看到我的编辑答案 – rslite 2008-09-19 07:04:17

回答

3

对于第一个问题 - IIRC你不能使用比较器对DataView进行排序。如果您只需对数字字段进行排序,则必须确保列类型是数字而不是字符串。一些代码将有助于阐明这一点。

对于第二个问题,你也不能直接在DataView中做到这一点。如果你真的需要基于在列数据的一些处理的记录进行排序,然后我会在一个阵列中的数据复制和阵列上使用的IComparer:

DataView dv = new DataView(dt); 
ArrayList lst = new ArrayList(); 
lst.AddRange(dv.Table.Rows); 
lst.Sort(new MyComparer()); 
foreach (DataRow dr in lst) 
    Debug.WriteLine(dr[0]); 

比较程序是这样的:

class MyComparer : IComparer 
    { 
     public int Compare(object x, object y) 
     { 
      DataRow rx = x as DataRow; 
      DataRow ry = y as DataRow; 
      string datax = (string)rx[colName]; 
      string datay = (string)ry[colName]; 
      // Process datax and datay here then compare them (ASC) 
      return datax.CompareTo(datay); 
     } 
    } 

这会增加内存消耗,因此您需要考虑是否有更好的方法来预处理表中的数据,以便您可以按列直接对DataView进行排序。

P.S. colName是您有兴趣排序的列的名称。用实际代码替换注释以从列中提取排序信息。您也可以使用此方法从更多列中提取排序信息。只要使用这样的事情:

int cmp = colAx.CompareTo(colAy); 
if (cmp != 0) 
    return cmp; 
cmp = colBy.CompareTo(colBx); 
return cmp; 

这将比较上升由可乐值,然后通过COLB值下降(不是第二个比较具有ŸX

编辑 :好的,我错误地解释了逗号分隔值这个词。从你的例子中,我认为你实际上是指具有千分隔符(1,000,000 =一百万)的数字。如果你在数据库中存储这样的数字,那么它必须是你使用文本字段,这应该是你的排序顺序是字母数字的原因。

基于这个假设,我会建议将该列的类型更改为数字,将正常数字保留在内部并仅在显示它们时格式化(使用千分隔符)。这种方式应该直接在DataView中工作,而不必复制数据。

0

对于场景中,我建立一个DataTable动态,并将其推到一个数据视图,我把数据视图到一个GridView,同时记得把数据视图到一个会话对象排序功能。

当GridView的用户来电排序列,我记得在会话对象中的数据视图,并建立数据视图的排序表达式是这样的:

dataview.sort = e.sortexpression + " " + e.Sortdirection; 

或者类似的规定。那么,什么ussually出来适合所有真正的字符串,例如

车;家;斯科特;扎克等等

但是,当我与逗号分隔值号码字段做同样的它出来像

900; 800; 700; 600; 200; 120; 1200; 12340;百万;

明白我的意思吗?它只是将项目排序为Alpha排序而不是Natural排序。我想我的数据视图自然是数字列正确像

120进行排序; 200; 600; 700; 800; 900; 1200; 12340;百万;

让我知道你可以做些什么来帮助我。
P.S.我已经浏览了无数关于如何做到这一点的文章,并且他们都说要推入列表/数组并且以这种方式进行,但是有没有更高效的方法?

1

这是丑陋的,但:

 DataView dv = GetDataViewSomewhere(); 

     //Naturally sort by COLUMN_TO_SORT_ON 
     try 
     { 
      List<string> rowList = new List<string>(); 
      foreach (DataRowView drv in dv) 
       rowList.Add((string)drv["COLUMN_TO_SORT_ON"]); 
      rowList.Sort(new NaturalComparer()); 
      Dictionary<string, int> sortValueHash = new Dictionary<string, int>(); 
      for (int i = 0; i < rowList.Count; i++) 
       sortValueHash.Add(rowList[i], i);          

      dv.Table.Columns.Add("NATURAL_SORT_ORDER", typeof(int)); 
      foreach (DataRowView drv in dv) 
       drv["NATURAL_SORT_ORDER"] = sortValueHash[(string)drv["COLUMN_TO_SORT_ON"]]; 
      dv.Sort = "NATURAL_SORT_ORDER";     
     } 
     catch (Exception) 
     {     
      DEBUG_TRACE("Could not naturally sort"); 
      dv.Sort = "COLUMN_TO_SORT_ON"; 
     } 

哪里NaturalComparerthis class

+0

无法真正复制并粘贴到这一点我的应用程序 – aron 2010-04-08 19:37:03