WPF 控件设计指南 - 时间线

标签 wpf user-controls collections

我正在为我们的一个应用程序开发控件。该控件将当前关注的日期显示为网格,X 轴是一天中的时间。 Y 轴本身没有刻度,而是将要显示的项目分开。控件的整体外观将非常类似于甘特图,显示一天中各种任务的时间。对于一个(非常粗略的)想法,请参阅下面的 ascii(非)艺术。

8      9     10     11     12      1      2      3      4      5      6
-----------------------------------------------------------------------------
|      |      |      |      |      |      |      |      |      |      |
|      ======================      |      |      |      |      |      |
|      |      |      ======================      |      |      |      |
|      |      |      |      |      |      |      ========      |      |
|      |      |      |      ===========================================
|      |      |      |      |      |      |      |      |      |      |
我已经制定了背景网格,以便它可以调整大小,并且将“当前时间”指示器实现为垂直蓝线,以显示我们与任务相关的位置。调整控件大小时,会重新计算当前时间指示器的位置,以确保它显示正确的时间。
我现在不确定的是如何实现代表任务项的水平条。我有一个包含开始时间、结束时间、名称和描述的任务实体,我希望控件包含这些实体的集合。我也希望这些实体来驱动显示。
过去,我在可视化对象集合方面的尝试涉及使用列表框和数据模板。如果可以将集合绑定(bind)到堆栈面板(进行垂直堆叠)或类似的东西,那就太好了,所以我可以有这样的东西:
<UserControl declarations here... >
    <UserControl.Resources>
        <ObjectDataProvider x:Key="myCollection" />
    </UserControl.Resources>
    <Grid Name="myBackgroundGrid" Margin="0,0,0,0" ... >stuff goes here to draw the background</Grid>
    <StackPanel ItemsSource="{Binding Source={StaticResource myCollection}}" />
</UserControl>
这甚至可能吗?如果可以,如何实现?

- 编辑 -
显示每个任务的“控件”不必比带有开始和结束时间的行以及任务名称的工具提示更复杂。目前,我不需要深入研究任务,尽管这可能会在以后出现。

最佳答案

假设您的数据类是这样的:

public class TimeLineEntry
{
    public string Name { get; set; }
    public DateTime Start { get; set; }
    public int Index { get; set; }
    public int Duration { get; set; }
}

您可以使用 ItemsControl将条目布置为矩形。
<ItemsControl ItemsSource="{Binding}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas IsItemsHost="True" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="{x:Type ContentPresenter}">
            <Setter Property="Canvas.Left" Value="{Binding Path=Start, Converter={StaticResource timeToPositionConverter}}" />
            <Setter Property="Canvas.Top" Value="{Binding Path=Index, Converter={StaticResource indexToPositionConverter}}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="TimeLineEntry">
            <Rectangle  Width="{Binding Duration}" Height="10" ToolTip="{Binding Name}" Fill="Red" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

在上面的 XAML 代码中,ItemsControl(它是基类 ListBox、ListView 等)的面板更改为 Canvas以便更好地定位元素。

您可以使用 ItemsControl.ItemTemplate 自定义项目的显示方式。

我已将 TimeLineEntry 类的 Start 和 Index 属性绑定(bind)到 ItemContainer 的 Canvas.Left 和 Canvas.Top 附加属性,并且我还使用值转换器将 DateTime 值转换为像素位置。

值(value)转换器的代码很简单。
public class IndexToPositionConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is int)
        {
            return ((int)value) * 10;
        }
        return 0;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

关于WPF 控件设计指南 - 时间线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1860224/

相关文章:

wpf - Textblock.TextTrimming 在网格内不起作用

java - PriorityBlockingQueue 逻辑上无界但实际上并非如此?

java - Java中的通用树实现

c# - Type.GetType() 返回 null

javascript - 将多个用户控件添加到一个表单时,Asp.Net 用户控件无法正常工作

Swift 4.2 奇怪的 -.map- 行为

c# - 如何使用 Avalonia 模拟 DataTrigger?

c# - 违反通用参数约束?

c# - 窗口句柄单击事件

c# - UserControl依赖于业务逻辑类