Search code examples
wpfcanvasitemscontrol

When using ItemsControl ItemsControl.ItemsPanel is set to Canvas, ContenPresenter comes in and break my Canvas properties on the children [WPF]


I am using an ItemsControl where the ItemsPanel is set to Canvas (see this question for more background information). The ItemsControl is performing as I want, and it works like a charm when adding a child element manually by putting it into ItemsControl.Items:

<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas IsItemsHost="True" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.Items>
        <Button Canvas.Left="500" Content="Button Text" />
    </ItemsControl.Items>
</ItemsControl>

Note the Canvas.Left property on the Button. This works like a charm, and the Button is placed 500 pixels from the left of the ItemsControl left side. Great!

However, When I am defining a ItemsSource binding to a List, the Canvas.left doesn't have any effect:

<ItemsControl ItemsSource="{Binding Elements}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas IsItemsHost="True" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Canvas.Left="500" Content="Button Text" />
        </DataTemplate>     
    </ItemsControl.ItemTemplate>
</ItemsControl> 

By inspecting the application during run time, I see one difference. The container ContentPresenter has been added between the Canvas and the button..

How can I set the Canvas.Left property on the ContentPresenter itself? Or is there another way to solve this problem?

Thanks to all!


Solution

  • there are several solutions coming to my mind:

    1. use a layout/rendertransform instead of the attached property
    2. use margin instead of the attached property
    3. derive from ItemsControl, and override the behavior how the child containers are generated. (GetContainerForItemOverride, IsItemItsOwnContainerOverride). This article is explaining quite nicely how it works: http://drwpf.com/blog/2008/07/20/itemscontrol-g-is-for-generator/