WPF绝对定位

发布于 2024-11-01 16:14:03 字数 2390 浏览 0 评论 0原文

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

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,但它们仍然在垂直方向上一个接一个地排列。

有什么想法吗?

我想我现在明白了。项目控件本身使其行为类似于堆栈面板。还有其他选择吗?

Possible Duplicate:
How to bind a canvas to a list of rectangles

A canvas in WPF uses absolute positions correct? I have a sitatution where I have rectangles on a canvas and they are behaving like they are being placed on a vertical stack panel.

I.e. I am placing a rectangle at 0,0, and the next one at 0,0, but it is appearing underneath the first one.

I know for instance that this works as I expected, i.e. the rectangles will overlap as expected,

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

But my situation is a bit more complicated than that,

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

My code has an items control in it, and it is binding to a list of shapes. These shapes bind to objects like this,

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

But all the shapes have the coordinates of 0,0, but they are still lining up one after the other vertically.

Any ideas?

I think I am getting it now though. The items control itself is making it behave like a stack panel. Any alternatives?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倒数 2024-11-08 16:14:04

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

Adding the ItemsControl as the only child of the Canvas is not what you want. It should be the panel of the ItemsControl:

<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <Canvas Grid.Column="0" Grid.Row="0" Background="{TemplateBinding Background}" Margin="0,30,0,0">
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

Further the items get wrapped, the attached properties will be ignored if you set them in the DataTemplate, it has to be done like this:

 <ItemsControl.ItemContainerStyle>
     <Style TargetType="{x:Type ContentPresenter}">
         <Setter Property="Canvas.Left" Value="{Binding X}"/>
         <Setter Property="Canvas.Top" Value="{Binding Y}"/>
     </Style>
 </ItemsControl.ItemContainerStyle>
尬尬 2024-11-08 16:14:03

您是正确的,画布使用绝对定位。在您的示例中,您已指定画布内每个矩形的顶部和左侧位置,但缺少矩形的宽度和高度属性,这就是它们可能无法按您想要的方式显示的原因。

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

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

You are correct that the Canvas uses absolute positioning. In your example, you have specified the top and left positions of each rectangle within the Canvas, but you are missing the Width and Height properties on the Rectangles, which is why they might not be displaying how you want.

The example below shows two overlapping 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文