Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding ContentPresenter in ItemsControl

Is there a way to avoid generation of ContentPresenter that ItemsControl wraps my items in? My ItemsControl is bound to a VM property and I'm using a DataTemplate in my ItemControl's Resources (without an x:Key) to customize the look of my collection objects. This all works fine, but inspecting through Snoop shows that all my collection objects are wrapped inside ContentPresenters and not directly added to the Panel. This fact is creating some other issues for me. Is there a way to avoid the extra wrapping?

Here's the 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>
like image 367
dotNET Avatar asked Aug 03 '15 13:08

dotNET


1 Answers

You could create a derived ItemsControl and override its GetContainerForItemOverride method:

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

Your ItemsControl XAML wouldn't set the ItemTemplate anymore, and have an ItemContainerStyle that directly targets the Ellipse:

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

As a note, in order to draw ellipses that are centered at XLoc and YLoc, you should replace the Ellipse control by a Path with an EllipseGeometry.

like image 127
Clemens Avatar answered Oct 12 '22 19:10

Clemens