2008-09-18 50 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