确定WPF元素相对于某个父级的边界矩形

19

我认为这是一个非常简单的请求,但是我在搜索中似乎找不到确定的答案。如何确定窗口中特定可视元素相对于其他父元素的边界?

我尝试使用LayoutInformation.GetLayoutSlot,但这似乎只返回0,0处的Rect,并未反映元素的实际位置。

我想要做的是使用RenderTargetBitmap对窗口进行“屏幕截图”,然后将其裁剪到特定的元素,但我无法获取元素的边界以知道要将位图裁剪到哪里!

4个回答

21

这很简单:

public static Rect BoundsRelativeTo(this FrameworkElement element,
                                         Visual relativeTo)
{
  return
    element.TransformToVisual(relativeTo)
           .TransformBounds(LayoutInformation.GetLayoutSlot(element));
}

实际上,将其放入单独的方法中可能有些过度。


8
GetLayoutSlot方法获取布局中为元素分配的空间,但如果该元素具有显式宽度/高度和/或转换,则实际元素大小可能会不同。要获取“真实”的大小矩形,请尝试使用element.RenderTransform.TransformBounds(new Rect(element.RenderSize)) - nmclean
这对我没用,参见下面Mauro Sampletro或DanW的答案,那个是有效的。 - Michael Brown

9
LayoutSlot选项对我完全没有作用。 最终结果是,它给了我一个相对于指定的父/祖先控件的子控件位置。
    public static Rect BoundsRelativeTo(this FrameworkElement child, Visual parent)
    {
        GeneralTransform gt = child.TransformToAncestor(parent);
        return gt.TransformBounds(new Rect(0, 0, child.ActualWidth, child.ActualHeight));
    }

1
这对我有用,被接受的答案没有。在.NET Framework 4.5.2中使用WPF中的网格边框。 - pauldendulk

5
考虑到这里提出的一些建议,我解决了这个问题。
item.TransformToVisual( relativeToElement )
    .TransformBounds( new Rect( item.RenderSize ) );

1

没事了,我最终成功地通过结合使用 LayoutInformation.GetLayoutSlot()(虽然我可能可以使用ActualWidth/ActualHeightRenderSize)和 UIElement.TranslatePoint()来解决这个问题。

看起来这似乎是一个相当复杂的解决方案,但其实它可以像这样简单:

myElement.GetBounds( relativeElement );

嗯,也许是时候使用扩展方法了。:)


1
我是说应该有。 - devios1
1
请问您能否展示完整的解决方案?我没能让它正常工作。它总是相对于某个父元素出现错误。目前,我正在使用myElement.PointToScreen(new Point())将所有内容转换为屏幕坐标,这对于处理WM_NCHITTEST来说还可以。但我仍然认为这是一种hack方法。 - ygoe
我们都很高兴你解决了问题。请在这里提供你的解决方案。 - Nasenbaer
@Nasenbaer 抱歉我已经有一段时间没有进行.NET开发了。我建议阅读TranslatePoint的文档。 - devios1

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