时间预​​订视觉显示视觉、时间

2023-09-03 01:42:11 作者:另类收藏者

我有一个系统,管理车辆和人员外,当你根据你应该能够看到的时间,他们都可以在这一天的日期上他们的名字点击。

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.