当使用ItemsControl ItemsControl.ItemsPanel设置为Canvas时,ContenPresenter将进入并在子项[WPF]上断开我的画布属性

当使用ItemsControl ItemsControl.ItemsPanel设置为Canvas时,ContenPresenter将进入并在子项[WPF]上断开我的画布属性,wpf,canvas,itemscontrol,Wpf,Canvas,Itemscontrol,我正在使用ItemsControl,其中ItemsPanel设置为Canvas(有关更多背景信息,请参阅问题)。 ItemsControl正在按我所希望的方式执行,当通过将子元素放入ItemsControl中手动添加子元素时,它就像一个符咒一样工作。Items: <ItemsControl> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas IsI

我正在使用ItemsControl,其中ItemsPanel设置为Canvas(有关更多背景信息,请参阅问题)。 ItemsControl正在按我所希望的方式执行,当通过将子元素放入ItemsControl中手动添加子元素时,它就像一个符咒一样工作。Items:

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

注意按钮上的Canvas.Left属性。这就像一个符咒,按钮位于ItemsControl左侧左侧500像素处。太好了

但是,当我定义与列表绑定的ItemsSource时,Canvas.left没有任何效果:

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

通过在运行时检查应用程序,我看到了一个区别。容器ContentPresenter已添加到画布和按钮之间

如何设置ContentPresenter本身的Canvas.Left属性?还是有别的办法解决这个问题


谢谢大家

我想到了几种解决方案:

  • 使用布局/渲染转换而不是附着的属性
  • 使用边距而不是附着的属性
  • 从ItemsControl派生,并重写如何生成子容器的行为。(GetContainerForItemOverride,IsItemItsOwnContainerOverride)。本文很好地解释了它的工作原理:

  • 可以使用ItemContainerStyle设置Canvas.Left属性:

    <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>
    
    
    
    按钮没有“Canvas”属性,因此您要做的是对宿主控件进行相对调用,但是由于项目和画布位于不同的模板中,因此没有直接链接,因此画布。在运行前,Left没有意义

    因此,您的方法无法找到要设置的左键,因此将丢失更改

    但是,setter仅在运行时实现,因此

    <Setter Property="Canvas.Left" Value="500" /> 
    
    
    
    将仅在生成对象后运行,因此具有相对关系


    否则,您可以使用确实属于按钮对象但仅在运行时解释的边距

    您还可以在ItemContainerStyle中绑定该值,它将使用与DataTemplate用作源的相同项。:-)你今天是我的英雄。非常感谢。