时间预订视觉显示 [英] Time Bookings Visual Display
问题描述
我有一个系统,管理车辆和人员外,当你根据你应该能够看到的时间,他们都可以在这一天的日期上他们的名字点击。
I have a system which manages Vehicles and Staff, when you click on their name based on a date you should be able to see the times that they are available on that day.
这将只显示1天根据所选择的previous表上的日期!所以,我需要1列,但时间可能是12:30-14:15等
It will only show 1 day based on the date chosen on the previous form! So I need 1 column but times could be 12:30-14:15 etc
视觉的东西是这样的:
视觉时代视觉时间
图:
我特地在创建一个自定义的控制或用户控制,但我对学科知识低,我已经花了几个小时,绕了一圈跑。
I have looked in to creating a custom control or user control but my knowledge on the subject is low and I've spent a few hours running around in a circle.
推荐答案
发布这个答案,因为OP提出请求:
Posting this answer because the OP requested it:
这是如何做到这一点的WPF:
This is how you do that in WPF:
<Window x:Class="MiscSamples.TimeBookings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MiscSamples"
Title="TimeBookings" Height="300" Width="300">
<Window.Resources>
<local:TimeRangeToVerticalMarginConverter x:Key="VerticalMarginConverter"/>
<local:TimeRangeHeightConverter x:Key="HeightConverter"/>
</Window.Resources>
<ScrollViewer>
<Grid>
<ItemsControl ItemsSource="{Binding Available}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1" Height="60">
<TextBlock Text="{Binding StringFormat='hh tt'}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl ItemsSource="{Binding Bookings}">
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Margin" Value="{Binding Converter={StaticResource VerticalMarginConverter}}"/>
<Setter Property="Height" Value="{Binding Converter={StaticResource HeightConverter}}"/>
<Setter Property="VerticalAlignment" Value="Top"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="#601050FF" BorderBrush="LightSkyBlue" BorderThickness="1"
x:Name="Border">
<Viewbox Stretch="Uniform">
<TextBlock Text="Booked" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="16">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-45"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Viewbox>
<Border.ToolTip>
<ToolTip>
<StackPanel>
<TextBlock>
<Run Text="From" FontWeight="Bold"/>
<Run Text="{Binding StartString, Mode=OneWay}"/>
</TextBlock>
<TextBlock>
<Run Text="To" FontWeight="Bold"/>
<Run Text="{Binding EndString,Mode=OneWay}"/>
</TextBlock>
</StackPanel>
</ToolTip>
</Border.ToolTip>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</ScrollViewer>
code背后:
public partial class TimeBookings : Window
{
public TimeBookings()
{
InitializeComponent();
DataContext = new TimeBookingsViewModel();
}
}
视图模型:
public class TimeBookingsViewModel
{
public ObservableCollection<DateTime> Available { get; set; }
public ObservableCollection<TimeRange> Bookings { get; set; }
public TimeBookingsViewModel()
{
Available = new ObservableCollection<DateTime>(Enumerable.Range(8, 11).Select(x => new DateTime(2013, 1, 1).AddHours(x)));
Bookings = new ObservableCollection<TimeRange>();
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);
}
}
和几个助手(转换器等等):
And a few helpers (Converters and such):
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 ,的数据绑定和 的WPF心态
- 这样可以使你的code后面几乎是空的,你的应用程序code真干净,通过只处理自己的类和属性,只留下用户界面。
- 在没有业主抽奖,没有P / Invoke的(知道是什么意思),没有复杂的尺寸/位置计算,没有蹩脚的程序上的绘图code。只有美丽的声明XAML和数据绑定的简单,简单的属性。的
- 在用户界面是通过使用2 ItemsControls 不同的的DataTemplates (一为背景小时箱,和其他的订单视觉重presentation)
- 在预订文本块是
Viewbox的
内一>这使得它延伸到可用大小。你可以改变,如果你想要的,但我无法想象一个更好的方法来使文本适合可用的空间,不同的预订。 - 我甚至花时间来添加漂亮的描述
工具提示
。您可以真的做你想做的在WPF。 - 在我强烈建议你阅读所有的链接材料在这篇文章中,大多是瑞秋的WPF心态和相关的博客文章。让我知道如果你需要进一步的帮助。
- The UI is separate from Data and Logic by using MVVM, DataBinding and The WPF Mentality
- This keeps your code behind almost empty and your application code really clean, by just dealing with your own classes and properties, and leaving the UI alone.
- No "owner draw", no P/Invoke (whatever that means), no complicated size/position calculations, and no crappy procedural "drawing code". Only beautiful declarative XAML and DataBinding to simple, simple properties.
- The UI is created by using 2 ItemsControls with different DataTemplates (one for the "background" hour boxes, and the other for the bookings visual representation)
- The "Booked" textblock is inside a
Viewbox
which makes it stretch to the available size. You can change that if you want, but I could not imagine a better way to make the text fit the available space for different bookings. - I even took the time to add the nice descriptive
ToolTip
. You can really do what you want in WPF. - I strongly suggest you read all the linked material in this post, mostly Rachel's "WPF Mentality" and related blog posts. Let me know if you need further help.
底线:
忘记的WinForms,它太局限,它没有(真正的)数据绑定,它需要大量的code少做,它不支持任意自定义级别,它迫使你创建低劣的Windows 95一样的用户界面。
WPF岩:只需复制和粘贴我的code在文件 - &GT;新建项目 - &GT; WPF应用程序
,看到的结果吧。
WPF Rocks: Just copy and paste my code in a File -> New Project -> WPF Application
and see the results for yourself.
这篇关于时间预订视觉显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!