wpfxamlitemscontrolitemtemplateitemspanel

Stretch line to width of Itemstemplate canvas in itemscontrol


I have this code. For some reason I can't get the contentpresenter to stretch to fill the width of the canvas. Several of my attempts are commented out in the xaml.

<ItemsControl ItemsSource="{Binding MarkerLocations, Mode=OneTime}" HorizontalContentAlignment="Stretch">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Top" Value="{Binding}" />
            <Setter Property="Canvas.Left" Value="0" />
            <!--Setter Property="Width" Value="{Binding Path=Width, RelativeSource={RelativeSource FindAncestor, AncestorType=Canvas, AncestorLevel=1}}"/-->
        </Style>
    </ItemsControl.ItemContainerStyle>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <!--Rectangle Stroke="Black" Height="2" Stretch="Fill"/-->
            <Line Stretch="Fill" X2="2" Y1="{Binding Mode=OneTime}" Y2="{Binding Mode=OneTime}" Stroke="Black" StrokeThickness="1"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

I have a feeling I'm not understanding the context of the ItemContainters.


Solution

  • If you want to bind to the width of stretching objects you should bind to the ActualWidth:

    {Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Canvas}}
    

    Edit: This may not be necessary

    Canvases have the habit of not occupying any space at all unless you tell them:

      <ItemsControl ItemsSource="{Binding MarkerLocations, Mode=OneTime}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas Background="Red"
                            HorizontalAlignment="Stretch"
                            VerticalAlignment="Stretch"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
      </ItemsControl>
    

    Setting its Background is a useful "layout-debugging" trick to see if its actually there. From there one of your approaches should work.