我有一个ObservableCollection<Performance>
需要以时间表的方式显示在WPF应用程序中。
演出除此之外还包括 StartTime 和位置,应按照以下方式进行组织:
Location | 14h - 15h | 15h - 16h | 16h - 17h | 17h - 18h
---------+-----------+-----------+-----------+----------
Loc #1 | Perf 1 | Perf 2 | Perf 3 | Perf 4
---------+-----------+-----------+-----------+----------
Loc #2 | Perf 5 | ...
---------------------+
...
我的持久层保证没有交叉点,即当有一个性能位于A并且从X点开始时,没有其他人会这样做。
我尝试了几种方法,主要是DataGrid
,因为这似乎是显而易见的选择,但我无法完成所需的工作。我很确定必须有某种解决方案不是完全“hacky”但我没有想出来。
是否可以按原样使用数据,或者ObservableCollection
是否需要在任何情况下重组?如何设法绑定DataGrid
和StartTime
上的Location
两者?或者我应该替换DataGrid
吗?
非常感谢任何帮助!
答案 0 :(得分:0)
您所尝试的内容称为透视,不幸的是,如果您事先不知道确切的列并希望从数据中构建所有内容,那就不那么容易了。
一种解决方案是在每次数据更改时将ObservableCollection
转换为DataTable
,然后让DataGrid
控件绑定到DataTable
AutoGenerateColumns="true"
}。
自{.NET}的早期版本以来,DataTable
类一直存在,并且与现代C#一起使用并不是特别优雅,但它确实允许您动态创建列,这是关键挑战转动数据时。
话虽如此,这里有一些代码来构建来自DataTable
的{{1}}:
ObservableCollction<Performance>
这样做是为了创造一个&#34;骨架&#34; private static DataTable GetPerformances(ObservableCollection<Performance> performances)
{
var dataTable = GetTableSkeleton(performances);
var performanceGroups = performances
.GroupBy(x => x.Location)
.OrderBy(x => x.Key);
foreach (var performanceGroup in performanceGroups)
{
var dataRow = dataTable.NewRow();
dataRow["Location"] = $"Loc {performanceGroup.Key}";
foreach (var performance in performanceGroup)
{
var columnName = GetColumnName(performance.StartTime);
dataRow[columnName] = $"Perf {performance.Id}";
}
dataTable.Rows.Add(dataRow);
}
return dataTable;
}
private static DataTable GetTableSkeleton(IEnumerable<Performance> performances)
{
var timeRanges = performances
.Select(x => x.StartTime)
.Distinct()
.OrderBy(x => x)
.Select(x => new DataColumn(GetColumnName(x)))
.ToArray();
var dataTable = new DataTable();
dataTable.Columns.Add("Location");
dataTable.Columns.AddRange(timeRanges);
return dataTable;
}
private static string GetColumnName(int startTime)
{
return $"{startTime}-{startTime + 1}";
}
首先从性能中提取列名称(确保没有重复项并按StartTime排序),然后将这些列添加到新的DataTable
。 (它还添加了“位置”列。)
然后,它通过循环分组并按位置排序的数据将所有数据添加到表中。
您可以通过挂钩DataTable
事件来确保DataGrid
始终保持更新。
这假设您的CollectionChanged
类具有以下三个整数属性:Performance
,Id
和StartTime
。