WPF控件设计指南 - 时间轴

5

我正在为我们的一个应用程序设计一个控件。该控件将当前聚焦的日期显示为网格,X轴表示一天中的时间。Y轴没有具体的刻度,而是将要显示的项目分开。整个控件的外观将非常类似于甘特图,显示各种任务在一天中的时间。如下是一个(非常粗略的)示意图。

8      9     10     11     12      1      2      3      4      5      6
-----------------------------------------------------------------------------
|      |      |      |      |      |      |      |      |      |      |
|      ======================      |      |      |      |      |      |
|      |      |      ======================      |      |      |      |
|      |      |      |      |      |      |      ========      |      |
|      |      |      |      ===========================================
|      |      |      |      |      |      |      |      |      |      |

我已经制定了背景网格,使其可调整大小,并实现了“当前时间”指示器,表示为垂直蓝线,以显示我们与任务的关系。当控件被调整大小时,当前时间指示器的位置将重新计算,以确保它显示正确的时间。
现在我不确定如何实现代表任务项的水平条形。我有一个任务实体,其中包含开始时间、结束时间、名称和描述,我希望控件包含这些实体的集合。我也希望这些实体驱动显示。
过去,我尝试将对象集合可视化的方法涉及使用列表框和数据模板。如果可以将集合绑定到堆栈面板(垂直堆叠)或类似的东西上,那将是很棒的,这样我就可以像这样做:
<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>

这个有可能吗?如果可以,如何实现呢?


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

1个回答

9
假设您的数据类如下所示:

假设您的数据类如下所示:

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属性绑定到ItemContainer的Canvas.Left和Canvas.Top附加属性,并且还使用值转换器将DateTime值转换为像素位置。
值转换器的代码很简单。
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();
    }
}

出色的回答。谢谢。 经过一点搜索,我找到了如何在我的控件.Resources部分中设置xaml中的IValueConverter:<src:IndexToPositionConverter x:Key="indexToPositionConverter"/>。 - ZombieSheep

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接