在ItemsControl中避免使用ContentPresenter

时间:2015-08-03 13:17:35

标签: wpf xaml datatemplate itemscontrol

有没有办法避免生成ContentPresenter ItemsControl包裹我的物品?我的ItemsControl绑定到VM属性,我在ItemControl的资源(没有DataTemplate)中使用x:Key来自定义我的集合对象的外观。这一切都很好,但通过Snoop检查显示我的所有集合对象都包含在ContentPresenter内,而不是直接添加到Panel中。这个事实为我创造了一些其他问题。有没有办法避免额外的包装?

这是XAML:

<ItemsControl ItemsSource="{Binding Path=Children}">
  <ItemsControl.Resources>
    <DataTemplate DataType="{x:Type vm:Ellipse}">
      <Ellipse Fill="{Binding Fill}" Stroke="{Binding Stroke}" />
    </DataTemplate>
  </ItemsControl.Resources>
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <Canvas Focusable="true" Margin="10" FocusVisualStyle="{x:Null}" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <ItemsControl.ItemContainerStyle>
    <Style>
      <Setter Property="Canvas.Left" Value="{Binding XLoc}" />
      <Setter Property="Canvas.Top" Value="{Binding YLoc}" />
      <Setter Property="Canvas.ZIndex" Value="{Binding ZOrder}" />
    </Style>
  </ItemsControl.ItemContainerStyle>
</ItemsControl>

1 个答案:

答案 0 :(得分:4)

您可以创建派生的ItemsControl并覆盖其GetContainerForItemOverride方法:

public class MyItemsControl : ItemsControl
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new Ellipse();
    }
}

您的ItemsControl XAML不再设置ItemTemplate,并且有ItemContainerStyle直接定位椭圆:

<local:MyItemsControl ItemsSource="{Binding Items}">
    <local:MyItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </local:MyItemsControl.ItemsPanel>
    <local:MyItemsControl.ItemContainerStyle>
        <Style TargetType="Ellipse">
            <Setter Property="Width" Value="100"/>
            <Setter Property="Height" Value="100"/>
            <Setter Property="Fill" Value="{Binding Fill}"/>
            <Setter Property="Stroke" Value="{Binding Stroke}"/>
            <Setter Property="Canvas.Left" Value="{Binding XLoc}"/>
            <Setter Property="Canvas.Top" Value="{Binding YLoc}"/>
            <Setter Property="Panel.ZIndex" Value="{Binding ZOrder}"/>
        </Style>
    </local:MyItemsControl.ItemContainerStyle>
</local:MyItemsControl>

作为注释,为了绘制以XLoc和YLoc为中心的椭圆,您应该用带有EllipseGeometry的Path替换Ellipse控件。