我对C#和WPF很新,我的曝光主要是自我造成的,所以我想我可能会遗漏一些明显的东西。然而,它似乎如此显而易见,它不会在几个小时的搜索中出现。
由于我只想尝试处理,所有数据都是随意的,简单的,有点傻。
我在名为dt1的DataTable中有这些数据:
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
(列分别为string,int和string)
我要做的是创建第二个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
显然某些东西正在保存,因为它在行的开头保存了名称,但同样明显的是它没有保存其余的数据点。
我的头骨在敲打这个特殊的墙壁时都是糊状的,所以我决定向那些比我更了解的人寻求帮助。
非常感谢任何见解或建议。
答案 0 :(得分: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 :(得分: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;