I have a ListBox, which is basically a canvas. The items shall be displayed as Rectangles. The position of the rectangles are bound to the items' data via the ListBoxItem's Canvas.Left and Canvas.Right property.
This is the ListBox' Template, which generates the Canvas:
<ListBox.Template>
<ControlTemplate>
<Canvas IsItemsHost="True"/>
</ControlTemplate>
</ListBox.Template>
The ListBox' ItemContainerStyle sets the position of the items:
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Canvas.Left">
<Setter.Value>
<MultiBinding Converter="{StaticResource ...}">
...
</MultiBinding>
</Setter.Value>
</Setter>
<Setter Property="Canvas.Right">
<Setter.Value>
<MultiBinding Converter="{StaticResource ...}">
...
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
This actually works. When I surround the ContentPresenter with a border, the border has the correct position and size.
Now, the rectangle's Width should equal the ListBoxItem's actual width. So the ItemTemplate looks like this:
<DataTemplate>
<Rectangle Height="..."
Width="{Binding ActualWidth,
RelativeSource={RelativeSource FindAncestor, AncestorType=ListBoxItem}}"
Fill="..."/>
</DataTemplate>
But with this binding applied, the rectangle is never displayed. When I set a constant width, everything renders correctly.
Is there a way to set the rectangle's position within the Canvas?
Update
Using the WPF Tree Visualizer I realized that this is probably a problem of the ContentPresenter's ActualWidth. The following screenshot shows that the Canvas.Left and Canvas.Right property are set correctly:

However, the ActualWidth property is set to 4 (the StrokeThickness of the contained Rectangle is 4). How can this layout problem be solved?
Furthermore, I have to amend my statement of above. Surrounding the ContentPresenter with a Border does not produce a correct result. Instead, the entire layout seems corrupt.
Update 2
The MSDN says the following:
The Canvas.Right offset of a child element does not affect the size of a parent Canvas.
If you specify them, the attached properties Canvas.Top or Canvas.Left take priority over Canvas.Bottom or Canvas.Right properties
So it seems that I have to specify the width explicitly, which should be a minor problem with an appropriate converter.
As stated in the question, it is not possible to define a control's size only with the
Canvas.LeftandCanvas.Rightproperties.The wanted behaviour could be achieved with a converter like the following (error handling omitted):
Use (add the converter as a resource):