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

走远了吗. 提交于 2019-11-29 03:29:21

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/

It is possible to set the Canvas.Left property using ItemContainerStyle:

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

Button Doesn't have a "Canvas" Property, so what you are doing is is making a relative call to the hosting control, however because the item and canvas are in different Templates there is no direct link, because of this the Canvas.Left is meaningless before runtime.

hence your method can't find a left to set so loses the change.

However Setters are only implemented at runtime so

<Setter Property="Canvas.Left" Value="500" /> 

will only run after the objects have been generated and hence do have a relative relationship.

Otherwise you can use the margin which does belong to the button object but again is only interpreted at runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!