WPF控制设计指南 - 时间表

时间:2009-12-07 14:15:02

标签: wpf user-controls collections

我正在为我们的某个应用程序设计控件。控件将当前聚焦的日显示为网格,X轴是一天中的时间。 Y轴没有这样的比例,而是将要显示的项目分开。控件的整体外观与甘特图非常相似,显示了各种任务的时间。对于(非常粗略的)想法,请参阅下面的ascii(非)艺术。

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

我制作了背景网格,使其可以调整大小,并将“当前时间”指示器实现为垂直蓝线,以显示我们与任务相关的位置。调整控件大小后,将重新计算当前时间指示器的位置,以确保其显示正确的时间。

我现在不确定的是如何实现代表任务项的水平条。我有一个具有开始时间,结束时间,名称和描述的任务实体,我希望控件包含这些实体的集合。我也喜欢这些实体来驱动显示器。

我对WPF的曝光非常有限,但在过去,我尝试可视化对象集合涉及使用列表框和数据模板。如果可以将一个集合绑定到一个堆栈面板或类似的东西,这将是很好的,所以我可以像这样semothing。 (我虽然StackPabnel因为它会为我处理垂直堆叠)

<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>

任何人都可以告诉我,我在这里想到的是否可能,并且(希望)给我一些关于如何实现我想做的事情的指导。

提前致谢。

- EDIT--
显示每个任务的“控件”不必比具有开始和结束时间的行更复杂,也不必是任务名称的工具提示。目前,我不需要能够钻进任务,虽然这可能会在以后发生。

1 个答案:

答案 0 :(得分: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属性绑定到Canvas.Left和Canvas.Top附加的ItemContainer属性,并且我还使用值转换器将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();
    }
}