Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将可观察到的集合组织到时间表中_C#_Wpf_Mvvm_Datagrid - Fatal编程技术网

C# 将可观察到的集合组织到时间表中

C# 将可观察到的集合组织到时间表中,c#,wpf,mvvm,datagrid,C#,Wpf,Mvvm,Datagrid,我有一个需要在WPF应用程序中以时间表方式显示的ObservableCollection 演出除其他演出外,还包括一个开始时间和一个地点,其组织方式如下: Location | 14h - 15h | 15h - 16h | 16h - 17h | 17h - 18h ---------+-----------+-----------+-----------+---------- Loc #1 | Perf 1 | Perf 2 | Perf 3 | Perf 4 ----

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

演出除其他演出外,还包括一个开始时间和一个地点,其组织方式如下:

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
,因为这似乎是一个显而易见的选择,但我无法实现所需的目标。我很确定一定有某种解决方案不是完全“黑”的,但我没有弄明白

是否可以按原样使用数据,或者在任何情况下,
可观察收集
是否需要重新构造?如何在
StartTime
Location
上绑定
DataGrid
?还是应该替换
DataGrid


任何帮助都将不胜感激

您正在尝试的是所谓的数据透视,不幸的是,如果您事先不知道确切的列,并且希望从数据中构建所有内容,那么要做到这一点就不那么容易了

一种解决方案是每次数据更改时将
observateCollection
转换为
DataTable
,然后使用
AutoGenerateColumns=“true”
DataGrid
控件绑定到
DataTable

DataTable
类在.NET的早期版本就已经存在,与现代C#一起使用并不特别优雅,但它允许您动态创建列,这是数据透视时的关键挑战

话虽如此,下面是一些代码,用于从一个
可观察到的冲突
构造一个
数据表

私有静态数据表GetPerformance(ObservableCollection性能)
{
var dataTable=GetTableSkeleton(性能);
var性能组=性能
.GroupBy(x=>x.Location)
.OrderBy(x=>x.Key);
foreach(性能组中的var性能组)
{
var dataRow=dataTable.NewRow();
数据行[“位置”]=“Loc{performanceGroup.Key}”;
foreach(性能组中的var性能)
{
var columnName=GetColumnName(performance.StartTime);
dataRow[columnName]=“性能{performance.Id}”;
}
dataTable.Rows.Add(dataRow);
}
返回数据表;
}
私有静态数据表GetTableSkeleton(IEnumerable性能)
{
var时间范围=性能
.选择(x=>x.StartTime)
.Distinct()
.OrderBy(x=>x)
.Select(x=>newdatacolumn(GetColumnName(x)))
.ToArray();
var dataTable=新的dataTable();
dataTable.Columns.Add(“位置”);
dataTable.Columns.AddRange(时间范围);
返回数据表;
}
私有静态字符串GetColumnName(int startTime)
{
返回$“{startTime}-{startTime+1}”;
}
这样做的目的是创建一个“骨架”
DataTable
,首先从性能中提取列名(确保没有重复项并按StartTime排序),然后将这些列添加到一个新的
DataTable
。(它还添加了位置列。)

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

通过挂接到
CollectionChanged
事件,可以确保您的
DataGrid
始终保持更新


这假设您的
性能
类具有以下三个整数属性:
Id
StartTime
、和
Location
,您尝试的是所谓的数据透视,不幸的是,如果您事先不知道确切的列,并且希望从数据构建所有内容,那么做起来就不那么容易了

一种解决方案是每次数据更改时将
observateCollection
转换为
DataTable
,然后使用
AutoGenerateColumns=“true”
DataGrid
控件绑定到
DataTable

DataTable
类在.NET的早期版本就已经存在,与现代C#一起使用并不特别优雅,但它允许您动态创建列,这是数据透视时的关键挑战

话虽如此,下面是一些代码,用于从一个
可观察到的冲突
构造一个
数据表

私有静态数据表GetPerformance(ObservableCollection性能)
{
var dataTable=GetTableSkeleton(性能);
var性能组=性能
.GroupBy(x=>x.Location)
.OrderBy(x=>x.Key);
foreach(性能组中的var性能组)
{
var dataRow=dataTable.NewRow();
数据行[“位置”]=“Loc{performanceGroup.Key}”;
foreach(性能组中的var性能)
{
var columnName=GetColumnName(performance.StartTime);
dataRow[columnName]=“性能{performance.Id}”;
}
dataTable.Rows.Add(dataRow);
}
返回数据表;
}
私有静态数据表GetTableSkeleton(IEnumerable性能)
{
var时间范围=性能
.选择(x=>x.StartTime)
.Distinct()
.OrderBy(x=>x)
.Select(x=>newdatacolumn(GetColumnName(x)))
.ToArray();
var dataTable=新的dataTable();
dataTable.Columns.Add(“位置”);
dataTable.Columns.AddRange(时间范围);
返回数据表;
}
私有静态字符串GetColumnName(int startTime)
{
返回$“{startTime}-{startTime+1}”;
}
这样做的目的是创建一个“骨架”
DataTable
,首先从性能中提取列名(确保没有重复项并按开始时间排序),然后
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}";
}