gpt4 book ai didi

c# - 将 Observable 集合组织到时间表中

转载 作者:行者123 更新时间:2023-12-03 10:44:17 26 4
gpt4 key购买 nike

我有一个 ObservableCollection<Performance>需要以时间表的方式显示在 WPF 应用程序中。

演出 除其他外,还包含 开始时间和一个 位置 并且应该像这样组织:

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无论如何都需要重组?我如何设法绑定(bind) DataGrid都在 StartTimeLocation ?或者我应该更换 DataGrid反正?

任何帮助将不胜感激!

最佳答案

您尝试进行的操作称为透视,不幸的是,如果您事先不知道确切的列并且想要从数据中构建所有内容,那么这并不容易。

一种解决方案是将您的 ObservableCollectionDataTable每次数据变化,然后有你的DataGrid控件绑定(bind)到 DataTableAutoGenerateColumns="true" .
DataTable类从 .NET 的早期版本就已经存在,并且与现代 C# 一起使用并不是特别优雅,但它确实允许您动态创建列,这是透视数据时的关键挑战。

话虽如此,这里有一些代码来构造 DataTable来自 ObservableCollction<Performance> :

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}";
}

这样做是创建一个“骨架” DataTable首先从表演中提取列名(确保没有重复并按 StartTime 排序),然后将这些列添加到新的 DataTable . (它还添加了 Location 列。)

然后,它通过循环遍历按位置分组和排序的数据,将所有数据添加到表中。

您可以确保您的 DataGrid通过 Hook CollectionChanged 始终保持更新事件。

这假设您的 Performance类具有以下三个整数属性: Id , StartTime , 和 Location .

关于c# - 将 Observable 集合组织到时间表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34816518/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com