我正在创建一个基本的甘特,作为事件日程的可视化表示。为此,我有一个ItemsControl来呈现StackPanel中的日程行项目。在该“父”ItemsControl中,我有另一个ItemsControl来呈现甘特图视图-基本上只是形状。如下所示:
<ItemsControl ItemsSource="{Binding ScheduleLines}"
Grid.Row="1"
Height="100">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"
Grid.Column="0"/>
<ItemsControl ItemsSource="{Binding Events}"
Grid.Column="1">
<ItemsPanelTemplate>
<components:ScheduleRowPanel/>
</ItemsPanelTemplate>
<ItemContainerTemplate>
<scheduleitems:ScheduleEventElement EventDate="{Binding EventDate}"
Status="{Binding Status}"/>
</ItemContainerTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
这个视图的datacontext有一个名为ScheduleLines
的ObservableCollection
。ScheduleLines
的每个项都有另一个Events
的可观察集合。
在子ItemsControl中,我有一个自定义面板,用于安排事件:
public class ScheduleRowPanel : Panel
{
//Scale and MinDate are dependency properties on this custom panel
protected override Size ArrangeOverride(Size finalSize)
{
foreach(UIElement child in Children)
{
ArrangeChild(child, MinDate, Scale, finalSize.Height);
}
return finalSize;
}
private void ArrangeChild(UIElement child, DateOnly minDate, double scale, double panelHeight)
{
if (child.GetType() == typeof(ScheduleEventElement))
{
ScheduleEventElement eventElement = (ScheduleEventElement)child;
DateOnly eventDate = eventElement.EventDate;
double xoffset = scale * (eventDate.DayNumber - minDate.DayNumber);
double yoffset = panelHeight / 2;
child.Arrange(new Rect(xoffset, yoffset, 50, 50));
}
else
{
throw new InvalidOperationException("Have not implemented any other type of schedule entity");
}
}
}
面板会排列下列事件,这些事件是具有填色的旋转矩形:
public class ScheduleEventElement : FrameworkElement
{
public DateOnly EventDate
{
get { return (DateOnly)GetValue(EventDateProperty); }
set { SetValue(EventDateProperty, value); }
}
// Using a DependencyProperty as the backing store for EventDate. This enables animation, styling, binding, etc...
public static readonly DependencyProperty EventDateProperty =
DependencyProperty.Register("EventDate", typeof(DateOnly), typeof(ScheduleEventElement), new PropertyMetadata(DateOnly.FromDayNumber(1)));
public EventStatus Status
{
get { return (EventStatus)GetValue(StatusProperty); }
set { SetValue(StatusProperty, value); }
}
// Using a DependencyProperty as the backing store for Status. This enables animation, styling, binding, etc...
public static readonly DependencyProperty StatusProperty =
DependencyProperty.Register("Status", typeof(EventStatus), typeof(ScheduleEventElement), new PropertyMetadata(EventStatus.Scheduled));
protected override void OnRender(DrawingContext drawingContext)
{
RectangleGeometry rectangle = new RectangleGeometry();
SolidColorBrush fill = new SolidColorBrush();
rectangle.Rect = new Rect(0, 0, 10, 0);
RotateTransform rotate = new RotateTransform();
rotate.CenterX = 0.5;
rotate.CenterY = 0.5;
rotate.Angle = 45;
rectangle.Transform = rotate;
switch (Status)
{
case EventStatus.Scheduled:
fill.Color = (Color)ColorConverter.ConvertFromString("#262626");
break;
case EventStatus.Early:
fill.Color = (Color)ColorConverter.ConvertFromString("#009d9a");
break;
case EventStatus.Late:
fill.Color = (Color)ColorConverter.ConvertFromString("#6929c4");
break;
}
drawingContext.DrawGeometry(fill, null, rectangle);
}
}
运行嵌套的ItemControl时出现以下错误:
我理解这是因为我需要将内部ItemControl修改为ItemsSource = {Binding Events}
,而不是<ItemsControl> <ItemsControl.ItemsSource/>
,但我不确定如何使用该语法指定项源。我的理解正确吗?如果正确,正确的语法是什么?
另外,我有ItemsContainerTemplate
的正确实现吗?或者这应该在ItemsTemplate
中吗?
谢谢
1条答案
按热度按时间dced5bon1#
不能只将
<ItemsPanelTemplate>
和<ItemContainerTemplate>
写入<ItemsControl>
标记中,需要将它们写入相关属性标记中:<ItemsControl.ItemsPanel>
和<ItemsControl.ItemTemplate>
中的至少一个。