【问题标题】:Positioning an element inside the Canvas by its center (instead of the top left corner) using only XAML in WPF在 WPF 中仅使用 XAML 将元素定位在画布内的中心(而不是左上角)
【发布时间】:2012-10-24 12:49:05
【问题描述】:

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

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

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

设置Canvas.LeftCanvas.Top

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

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

【问题讨论】:

    标签: wpf xaml canvas centering


    【解决方案1】:

    XAML 和绑定看起来非常强大,但有时一些简单的问题需要非常复杂的解决方案。在我的绑定库中创建这样的绑定就像写 element.Center = positionelement.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 没有所描述的行为。

    【讨论】:

    • 太棒了!非常感谢!
    【解决方案2】:

    至少对于 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>
    

    【讨论】:

      【解决方案3】:

      这个解决方案对我有用Center text at a given point on a WPF Canvas。他使用 MultiBinding 和自定义 Converter 来调整元素的边距。太棒了!

      【讨论】:

      • 我已经提到过这样的解决方案。正如我所说,我想要一个完全声明性的仅 XAML 解决方案。
      【解决方案4】:

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

      【讨论】:

      • 你能发布你的 xaml 吗?
      猜你喜欢
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      • 2017-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多