时间预订视觉显示

我有一个管理车辆和员工的系统,当您根据日期点击他们的名字时,您应该能够看到他们当天可用的时间。

它只会根据前一个表格中选择的日期显示1天! 所以我需要1列,但时间可能是12:30-14:15等

像这样的视觉效果:

视觉时间视觉时间

图片:

在此处输入图像描述

我已经研究过创建一个自定义控件或用户控件,但我对这个主题的了解很少,我花了几个小时绕圈跑了几个小时。

发布此答案是因为OP要求:

这就是你在WPF中的表现:

在此处输入图像描述

                                                       

代码背后:

 public partial class TimeBookings : Window { public TimeBookings() { InitializeComponent(); DataContext = new TimeBookingsViewModel(); } } 

视图模型:

 public class TimeBookingsViewModel { public ObservableCollection Available { get; set; } public ObservableCollection Bookings { get; set; } public TimeBookingsViewModel() { Available = new ObservableCollection(Enumerable.Range(8, 11).Select(x => new DateTime(2013, 1, 1).AddHours(x))); Bookings = new ObservableCollection(); Bookings.Add(new TimeRange(8, 0, 9, 50) {Base = TimeSpan.FromHours(8)}); Bookings.Add(new TimeRange(10, 0, 11, 00) { Base = TimeSpan.FromHours(8) }); Bookings.Add(new TimeRange(12, 00, 13, 30) { Base = TimeSpan.FromHours(8) }); } } 

数据项:

 public class TimeRange { public TimeSpan Base { get; set; } public TimeSpan Start { get; set; } public TimeSpan End { get; set; } public string StartString { get { return new DateTime(Start.Ticks).ToString("hh:mm tt"); } } public string EndString { get { return new DateTime(End.Ticks).ToString("hh:mm tt"); } } public TimeRange(int starthour, int startminute, int endhour, int endminute) { Start = new TimeSpan(0, starthour, startminute, 0); End = new TimeSpan(0, endhour, endminute, 0); } } 

还有一些助手(转换器等):

 public class TimeRangeToVerticalMarginConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (!(value is TimeRange)) return null; var range = (TimeRange) value; return new Thickness(2, range.Start.TotalMinutes - range.Base.TotalMinutes, 2, 0); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } public class TimeRangeHeightConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (!(value is TimeRange)) return null; var range = value as TimeRange; return range.End.Subtract(range.Start).TotalMinutes; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } 
  • 通过使用MVVM , DataBinding和WPF Mentality ,UI与数据和逻辑分离
  • 通过处理您自己的类和属性,以及单独使用UI,这可以使您的代码几乎为空,并且您的应用程序代码非常干净。
  • 没有“所有者绘制”,没有P / Invoke(无论这意味着什么),没有复杂的大小/位置计算,也没有蹩脚的程序“绘图代码”。 只有漂亮的声明式XAML和DataBinding才能实现简单,简单的属性。
  • 通过使用具有不同DataTemplates的 2个ItemsControl创建UI(一个用于“背景”小时框,另一个用于预订视觉表示)
  • “Booked”文本块位于Viewbox内部,可以扩展到可用的大小。 如果你愿意,你可以改变它,但我无法想象一种更好的方法来使文本适合不同预订的可用空间。
  • 我甚至花时间添加了很好的描述性ToolTip 。 你可以在WPF中真正做到你想要的。
  • 我强烈建议你阅读这篇文章中的所有链接材料,主要是Rachel的“WPF Mentality”和相关的博客文章。 如果您需要进一步的帮助,请告诉我。

底线:

忘记winforms,它太有限了,它没有(真正的)数据绑定,它需要大量的代码来做更少的事情,它不支持任何级别的自定义,它迫使你像UI一样创建糟糕的Windows 95。

WPF Rocks :只需将我的代码复制并粘贴到File -> New Project -> WPF Application然后自己查看结果。

评估开发控件所花费的时间,将其乘以您的成本/小时,添加您将(肯定)产生的一些错误,并将其与一些经过validation的测试解决方案进行比较:

http://www.telerik.com/products/winforms/scheduler.aspx

http://www.devexpress.com/Products/NET/Controls/WinForms/Scheduler/

我建议你买你的控件(或者一些)。

你最好的选择是创建一个inheritance自类似控件的自定义控件,对于你的例子,沿着图片框的线条可能是有益的。 对于一个(略微过时的C ++)自定义控件,请参阅: http : //msdn.microsoft.com/en-us/library/ms364048( v = vs.80).aspx

至于自定义绘图设置: http : //msdn.microsoft.com/en-us/library/windows/desktop/bb761817(v = vs。85).aspx

作为概括,该想法如下:捕获WM_PAINT事件,并在该事件中向控件渲染预先绘制的图像(这通常通过创建绘制表面,然后将其复制到可渲染的疼痛中来完成 – 控制区域)这种方法可以避免任何“闪烁”。

绘图命令大多是简单的’drawline(xy_start,xy_end)。

最后,为了处理一天中的时间,如果你选择(rendersurface.height /(24 * 60)),你将有一个从像素到时间的转换。 例如:

 double convert_Size = (rendersurface.height / (24*60)); //height / Hours_in_day * Minites int time = (hour * 60) + minite_past_hour; Pixels_from_top = time * convert_Size; 

Pixels_from_top现在是白天该时间的像素y坐标。