我有以下字段的表格,
table Shows,
Id Name Time
1 A 7/28/2010 11:15:00 AM
2 B 7/29/2010 8:50:00 AM
3 C 7/29/2010 8:55:00 AM
我有一个对象显示包含来自所有字段的数据。现在我想要一个用户界面, 它显示所有日子每小时的节目数量..
Date 7/28/2010
Hours Count
11-12 1
Date 7/29/2010
Hours Count
8-9 2
我不知道我将如何在C#(它的逻辑)中做到这一点。另外,有没有类似于我在PHP中使用C#的爆炸功能。因为我的数据库字段有价值 7/29/2010 8:55:00 AM我想打破日期和时间。任何人都可以帮助构建上述UI的逻辑吗?
由于我想显示每个日期的所有小时数及其计数,我是否必须使用列表框作为日期和另一个列表框,包含该日期的所有小时数和计数?您能告诉我该怎么做吗?
答案 0 :(得分:4)
假设您能够使用LINQ,那么您可以非常轻松地在C#中进行所有分组和排序。 (我假设只是一个DateTime对象列表而不是完整的Show对象 - 看起来你可以通过一个简单的LINQ Select语句获得每个Show的DateTime。)
var shows = new[]
{
new DateTime(2010, 7, 28, 11, 15, 0),
new DateTime(2010, 7, 29, 8, 50, 0),
new DateTime(2010, 7, 29, 8, 55, 0)
};
var dates = shows.GroupBy(d => d.Date).OrderBy(d => d.Key);
foreach (var date in dates)
{
Console.WriteLine("Date {0}", date.Key.ToShortDateString());
var hours = date.GroupBy(d => d.Hour).OrderBy(d => d.Key);
Console.WriteLine("\tHours\tCount");
foreach (var hour in hours)
Console.WriteLine("\t{0}-{1}\t{2}", hour.Key, (hour.Key+1)%24, hour.Count());
}
这提供了输出:
Date 7/28/2010
Hours Count
11-12 1
Date 7/29/2010
Hours Count
8-9 2
请注意,这只是一个简单的控制台应用程序示例。您尚未指定使用的GUI技术(WinForms,WPF),因此我将其留作练习来获取分组结果并将其应用于GUI。
编辑:这是XAML中的示例格式,使用嵌套的ItemsControls和DataBinding连接到LINQ语句。
<ItemsControl Name="ShowDates" ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<HeaderedContentControl HeaderStringFormat="Date: {0}">
<HeaderedContentControl.Header>
<StackPanel>
<TextBlock Text="{Binding Path=DateString, StringFormat='Date: {0}'}" />
<TextBlock Margin="20,1,1,1" Text="Hour : Shows"/>
</StackPanel>
</HeaderedContentControl.Header>
<ItemsControl Name="HoursList" Margin="20,1,1,1" ItemsSource="{Binding Path=Hours}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}-{1} : {2}">
<MultiBinding.Bindings>
<Binding Path="HourStart" />
<Binding Path="HourEnd" />
<Binding Path="Count" />
</MultiBinding.Bindings>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</HeaderedContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
这使用我原始LINQ语句的修改版本,以便更容易连接DataBinding。此代码位于我的测试窗口的构造函数中。
var result =
shows
.GroupBy(d => d.Date)
.Select(gp => new{
Date = gp.Key,
DateString = gp.Key.ToShortDateString(),
Hours = gp.GroupBy(d => d.Hour)
.Select(hgp => new {
HourStart = hgp.Key,
HourEnd = (hgp.Key + 1) % 24,
Count = hgp.Count()
})
.OrderBy(h => h.HourStart)
});
ShowDates.DataContext = result;
答案 1 :(得分:3)
大多数数据库都具有转换功能。例如,与SQL Server一样,您可以转换日期并对其进行格式化,使其在convert关键字中显示为7/29/2010。此外,您可以使用SQL中的datepart函数来提取第一个小时(除非小时是12,否则您必须通过添加一个来计算第二个小时,然后返回1,这可以通过函数完成)。
按日期分组,然后按小时范围分组,然后计算出现次数...是逻辑。
HTH。
答案 2 :(得分:2)
至于你的DateTime问题,因为7/29/2010 8:55:00 AM
是一个有效的DateTime,你可以使用解析
System.DateTime dateTime;
System.DateTime.TryParse("7/29/2010 8:55:00 AM", out dateTime);
var date = dateTime.Date;
var time = dateTime.TimeOfDay;
有各种其他属性和方法可供选择。如果您只想要字符串,可以使用
var timeString = dateTime.ToString("hh:mm");
在C#中,如果使用日期,数字,时间等“常规”类型的数据,则很少需要进行字符串操作
答案 3 :(得分:0)
您的SQL语句可用于将数据分解为分组。例如,这是我将使用的SQL语句(您在第一列中看到的奇怪的解析只是我从日期时间对象中删除时间的方式):
SELECT
CONVERT(DATETIME, FLOOR(CONVERT(FLOAT, DateTimeColumnName))) as [Date],
DATEPART(Hour, DateTimeColumnName) as [Hour],
Count(*) as [Count]
FROM Shows
GROUP BY
FLOOR(CONVERT(FLOAT, DateTimeColumnName)),
DATEPART(Hour, DateTimeColumnName)
这将返回一个包含日期,小时以及满足该条件的记录数的数据集。类似的东西:
[Date] [Hour] [Count]
7/28/2010 00:00:00 11 1
7/29/2010 00:00:00 8 2
只需获取此数据并根据需要在UI中对其进行格式化。
关于您的其他问题,DateTime对象包含不同时间部分的属性,因此只需将日期时间数据转换为像Chad建议的DateTime对象。