14

关于在 a 中定位元素的常见问题Canvas是“如何定位元素的中心(而不是左上角)”。

提出了几种解决方案,但它们都有缺点。

Canvas.Left最简单的解决方案是在以编程方式设置和Canvas.Top属性期间适应元素大小。这有效,但只有一次。此解决方案不支持绑定,并且在更改元素大小时会中断。您也不能设置Canvas.LeftCanvas.Top使用

另一组解决方案涉及使用RenderTransform或的平移转换Margin。这些解决方案需要将一些属性绑定到-0.5 * Widthor -0.5 * Height。此类绑定需要创建自定义ValueConverter并且仅使用 XAML 是不可能创建的。

那么,有没有一种简单的方法可以在画布内定位元素,以便它Canvas.LeftCanvas.Top元素的中心相对应,并且大小和位置属性都可以绑定到其他一些属性?

4

4 回答 4

11

XAML 和绑定看起来非常强大,但有时一些简单的问题需要非常复杂的解决方案。在我的绑定库中,创建这样的绑定就像编写element.Center = positionor一样简单element.TopLeft = position - element.Size / 2,但不要让我得意忘形。

我找到了一个非常简单的解决方案,它只使用 XAML 并支持绑定元素的大小和位置属性。似乎当 WPF 控件也设置了对齐StretchCenter放置在画布内时,元素“倾向于”作为(Canvas.Left, Canvas.Top)点居中(我们想要的状态),但被放置在同(Canvas.Left, Canvas.Top)一点的“角板”停止. 我怎么知道这个“万有引力”?Margin当您通过将元素的 设置为负值来缓和块时,这一点很明显。设置负边距允许元素向其中心目标移动。元素移动直到Margin到达(-Height / 2, -Width / 2),使元素完全居中在(Canvas.Left, Canvas.Top)观点。进一步的更改不会导致任何移动,因为元素已经完美定位。

解决方案:设置Margin="-1000000".

所以在下面的代码中,椭圆都以 (200, 200) 点为中心。第一个椭圆具有对应于椭圆中心LeftTop属性,可以轻松地将它们与其他一些对象的属性绑定。

<Canvas>
    <Ellipse Width="100" Height="100" Canvas.Left="200" Canvas.Top="200" Opacity="0.5" Fill="Red" Margin="-100000" />
    <Ellipse Width="100" Height="100" Canvas.Left="150" Canvas.Top="150" Opacity="0.5" Fill="Blue" />
</Canvas>

不好的是这个解决方案只适用于 WPF。Silverlight 和 WinRT 没有所描述的行为。

于 2012-11-04T14:17:51.043 回答
4

至少对于 Shapes 来说,更简单的是使用带有适当几何图形的路径:

<Canvas>
    <Path Canvas.Left="200" Canvas.Top="200" Fill="Red" Opacity="0.5">
        <Path.Data>
            <EllipseGeometry RadiusX="50" RadiusY="50"/>
        </Path.Data>
    </Path>
</Canvas>
于 2012-11-04T15:33:11.587 回答
1

我通过将画布放入 2x2 网格的右下角单元格来解决这个问题。这使得 0,0 坐标成为网格的中心,然后您可以相对于它进行所有绘图。

于 2016-06-26T05:07:47.580 回答
0

该解决方案对我有用 在 WPF Canvas 上的给定点居中文本。他使用 MultiBinding 和自定义 Converter 来调整元素的边距。杰出的!

于 2014-04-24T19:58:26.360 回答