WPF绝对定位

6

可能重复:
如何将画布绑定到矩形列表

在 WPF 中,画布使用的是绝对位置,对吗?我有一个情况,在画布上有矩形,它们的行为就像被放置在垂直堆栈面板上。

也就是说,我把一个矩形放在 0,0,下一个也放在 0,0,但它出现在第一个矩形的下方。

我知道,例如这个工作方式符合我的预期,即矩形将按预期重叠。

<Canvas>
    <Rectangle Canvas.Top="50" Canvas.Left="50" Width="50" Height="50"  Fill="AliceBlue" />
    <Rectangle Canvas.Top="60" Canvas.Left="60" Width="50" Height="50"  Fill="Pink" />
</Canvas>

但我的情况比那要复杂一些,

<Canvas Name="DrawingCanvas" Grid.Column="0" Grid.Row="0" Background="{TemplateBinding Background}" Margin="0,30,0,0">
    <ItemsControl Name="LineContainer" ItemsSource="{Binding Shapes}">
        <ItemsControl.Resources>
            <DataTemplate DataType="{x:Type Models1:Rectangle}">
                <Rectangle Width="30" Height="30" Fill="Aquamarine" Canvas.Left="{Binding X}" Canvas.Top="{Binding Y}" >
                    <Rectangle.LayoutTransform>
                        <RotateTransform Angle="{Binding Angle}"></RotateTransform>
                     </Rectangle.LayoutTransform>
                 </Rectangle>
             </DataTemplate>
         </ItemsControl.Resources>
     </ItemsControl>
 </Canvas>

我的代码中有一个项控件,它绑定到一组形状的列表。这些形状绑定到对象,如下所示,
public class Rectangle : IShape, INotifyPropertyChanged
{
    private double angle;

    public string Text { get; set; }
    public double X { get; set; }
    public double Y { get; set; }
    public double Angle {
        get
        {
            return angle;
        }
        set
        {
            if (angle != value)
            {
                angle = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("Angle"));
                }
            }
        }
    }
    public Point Position { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
}

但所有的形状都有0,0的坐标,但它们仍然垂直地排列在一起。

有什么想法吗?

我现在明白了。项控件本身使其表现得像堆栈面板。有其他替代方案吗?


你能澄清一下你的意思吗?你问如何使用绝对位置,但你甚至说你已经得到了绝对位置。这不是你想要的吗?还是你希望它们相对于彼此是相对位置? - Jeff Mercado
我会更新问题的更多内容。 - peter
答案在这里,https://dev59.com/RFbTa4cB1Zd3GeqP8z6L - peter
2个回答

2
将ItemsControl作为Canvas的唯一子元素添加并不是您想要的。它应该是ItemsControl的面板:
<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <Canvas Grid.Column="0" Grid.Row="0" Background="{TemplateBinding Background}" Margin="0,30,0,0">
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

在进一步包装项的情况下,如果您在DataTemplate中设置了附加属性,则它们将被忽略,必须像这样进行设置:
 <ItemsControl.ItemContainerStyle>
     <Style TargetType="{x:Type ContentPresenter}">
         <Setter Property="Canvas.Left" Value="{Binding X}"/>
         <Setter Property="Canvas.Top" Value="{Binding Y}"/>
     </Style>
 </ItemsControl.ItemContainerStyle>

谢谢,但那不起作用。ContentPresenter是什么?也许ContentPresenter需要改成其他的东西。 - peter
在MSDN上查找。如果它不接受TargetType,请省略它,我认为应该可以正常工作。 - H.B.
你上面回答的那个不起作用。你对我另一个问题的回答有效。 - peter
实际上,当然它不起作用,你的设置完全错误。已更新答案。 - H.B.

2

您说得对,Canvas使用绝对定位。在您的示例中,您已指定了Canvas中每个矩形的顶部和左侧位置,但是您缺少Rectangles的宽度和高度属性,这就是为什么它们可能不能按照您想要的方式显示。

下面的示例显示了两个重叠的矩形。

<Canvas>
    <Rectangle Canvas.Top="50" Canvas.Left="50" Width="50" Height="50"  Fill="AliceBlue" />
    <Rectangle Canvas.Top="60" Canvas.Left="60" Width="50" Height="50"  Fill="Pink" />
</Canvas>

好的,你说得很有道理。我的情况有点复杂。我会更新我的问题。你确实证明了它们会重叠。 - peter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接