2014-01-07 41 views
2

我對C#和WPF很新穎,我的曝光大部分都是自我造成的,所以我想我可能會錯過某些明顯的東西。然而,它似乎是,所以很明顯,它沒有顯示在幾個小時的搜索。DataTable不能保持附加值

因爲我只是想解決處理問題,所有的數據都是任意的,簡單的和有點愚蠢的。

我有一個DataTable名爲DT1這樣的數據:

Name Count Date 
Fred 1  12/01/13 
Fred 2  12/02/13 
Fred 3  12/03/13 
Fred 4  12/04/13 
Barney 4  12/01/13 
Barney 3  12/02/13 
Barney 2  12/03/13 
Barney 1  12/04/13 
Wilma 1  12/01/13 
Wilma 2  12/02/13 
Wilma 3  12/03/13 
Wilma 4  12/04/13 
Betty 4  12/01/13 
Betty 3  12/02/13 
Betty 2  12/03/13 
Betty 1  12/04/13 

(列是字符串,整數和字符串,分別)

我想要做的就是創建一個DataTable的第二帶每一行對應一個名稱,並在一個單獨的列中顯示每個日期計,正是如此:

Name 12/01/13 12/02/13 12/03/13 12/04/13 
Fred 1   2   3   4 
... 

下面是我用填充第二DataTable中的代碼:

DataTable dt2 = new DataTable(); 

//add columns for the target dates 
dt2.Columns.Add("Name", typeof(string)); 
for (int n = 1; n < 5; n++) 
{ 
    dt2.Columns.Add(String.Format("12/0{0}/13", n.ToString()), typeof(int)); 
} 

DataRow pivotRow = dt2.NewRow(); 

foreach (DataRow row in dt1.Rows) //step through the rows in the source table 
{ 
    if (pivotRow[0].ToString() != row[0].ToString()) //if this is a "new" name in the data set 
    { 
     if (pivotRow[0].ToString() != "") //and it's not the first row of the data set 
      dt2.Rows.Add(pivotRow); //add the row we've been working on 
     pivotRow = dt2.NewRow(); //create a new row for the "next" name 
     pivotRow[0] = row[0].ToString(); //add the "next" name to the name column 
    } 
    //match the string date stored in column 2 of the source DataTable to the column name in the target one, and put the associated int value in that column 
    pivotRow[row[2].ToString()] = (int)row[1]; 
} 
//once we've finished the whole source DataTable, add the final row to the target DataTable 
dt2.Rows.Add(pivotRow); 

//at this point, looking at it through the locals window everything *appears* to be peachy in dt2 

GridView.ItemsSource = dt2.DefaultView; //and here, it's all the pits. 

這是顯示在DataGrid:

Name  12/01/13 12/02/13 12/03/13 12/04/13 
Fred 
Barney 
Wilma 
Betty 

說白了東西是越來越保存,因爲它在行的開頭保存的名字,但同樣簡單的是,它不節能其餘的數據點。

我的頭骨全是因爲撞在這堵牆上而變得糊糊的,所以我決定向那些比我知道得多(好得多)的人尋求幫助。

任何見解或建議將不勝感激。

回答

2

如果您在調試時查看輸出窗口,當網格嘗試顯示數據時,您應該注意到一整串綁定錯誤。問題在於使用「/」字符來解析綁定到底層對象,所以它無法從視圖中獲取數據。

您可以通過更換「/」字符的ColumnName,但將其放置在標題得到這個工作。

//add columns for the target dates 
DataTable dt2 = new DataTable(); 
dt2.Columns.Add("Name", typeof(string)); 
for (int n = 1; n < 5; n++) 
{     
    var dataColumn = dt2.Columns.Add(String.Format("12_0{0}_13", n), typeof (int)); 
    dataColumn.Caption = String.Format("12/0{0}/13", n);     
} 

DataRow pivotRow = dt2.NewRow(); 

foreach (DataRow row in dt1.Rows) //step through the rows in the source table 
{ 
    if (pivotRow[0].ToString() != row[0].ToString()) //if this is a "new" name in the data set 
    { 
     if (pivotRow[0].ToString() != "") //and it's not the first row of the data set 
      dt2.Rows.Add(pivotRow); //add the row we've been working on 
     pivotRow = dt2.NewRow(); //create a new row for the "next" name 
     pivotRow[0] = row[0].ToString(); //add the "next" name to the name column 
    } 
    //match the string date stored in column 2 of the source DataTable to the column name in the target one, replacing the '/', and put the associated int value in that column 
    pivotRow[row[2].ToString().Replace("/", "_")] = (int)row[1]; 
} 
//once we've finished the whole source DataTable, add the final row to the target DataTable 
dt2.Rows.Add(pivotRow); 
+1

哦,對小綠蘋果的熱愛。現在我比我預期的更尷尬。謝謝,那是做的。我只是將連字符換成斜線,他們會爲我的目的工作得很好。另外,非常感謝你的回答。 – NatCh

+0

+1「for the love of green green apples」 – Matt

2

這裏是將任意日期,並在原始數據表名的任意順序工作的解決方案:

DataTable dt2 = new DataTable(); 
dt2.Columns.Add("Name", typeof(string)); 

IEnumerable<DateTime> distinctDates = dt1.AsEnumerable().Select(row => (DateTime)row["Date"]).Distinct().OrderBy(date => date); 
foreach (var distinctDate in distinctDates) 
{ 
    dt2.Columns.Add(distinctDate.ToString("MM__dd__yy", CultureInfo.InvariantCulture), typeof(int)); 
} 

IEnumerable<string> distinctNames = dt1.AsEnumerable().Select(row => (string)row["Name"]).Distinct(); 
foreach (var distinctName in distinctNames) 
{ 
    DataRow outputRow = dt2.NewRow(); 
    outputRow["Name"] = distinctName; 

    IEnumerable<Tuple<int, DateTime>> inputRowsForName = dt1.AsEnumerable() 
     .Where(row => (string)row["Name"] == distinctName) 
     .Select(row => new Tuple<int, DateTime>((int)row["Count"], (DateTime)row["Date"])); 

    foreach (var inputRowForName in inputRowsForName) 
    { 
     string columnName = inputRowForName.Item2.ToString("MM__dd__yy", CultureInfo.InvariantCulture); 
     outputRow[columnName] = inputRowForName.Item1; 
    } 
    dt2.Rows.Add(outputRow); 
} 

GridView.ItemsSource = dt2.DefaultView; 
+0

我確信一旦我對C#有足夠的勝任力,我會覺得這很有用,因爲它對我有意義!謝謝。 :) – NatCh

+0

@NatCh沒問題。您可能不熟悉的部分是「Where」,「Select」等方法。這些都是所謂的LINQ擴展方法,您可以像使用SQL和數據庫表一樣使用它們來查詢和處理列表。 – mrzli

+0

不,我遵循LINQ/SQL的相當好的部分 - 我最近一直在努力處理這些問題。這是枚舉數,元組和lambda表達式使我逃脫。我承認他們,並且知道他們是什麼,但不夠好跟隨或使用他們。 (聳肩) – NatCh