如何在运行时确定C#中WPF控件的边界?

时间:2022-09-02 13:33:05

I have a Window with several Frame controls and would like to find the Bounds/Rectangle of the controls at runtime. They go into a grid on the window using XAML with Height/Width/Margin attributes.

我有一个带有几个Frame控件的Window,想在运行时找到控件的Bounds / Rectangle。它们使用具有高度/宽度/边距属性的XAML进入窗口的网格。

The Frame control doesn't have Bounds, Rect, Top or Left properties.

Frame控件没有Bounds,Rect,Top或Left属性。

The purpose is to test each frame to see if the mouse is inside when other events occur. My current work around is to set/clear boolean flags in the MouseEnter and MouseLeave handlers but there must be a better way. It could be obvious because I am new to C# WPF and .NET.

目的是测试每个帧以查看其他事件发生时鼠标是否在内部。我目前的工作是在MouseEnter和MouseLeave处理程序中设置/清除布尔标志,但必须有更好的方法。这很明显,因为我是C#WPF和.NET的新手。

3 个解决方案

#1


3  

Why don't you just test the IsMouseOver or IsMouseDirectlyOver properties ?

为什么不直接测试IsMouseOver或IsMouseDirectlyOver属性?

#2


5  

Although others have met the need, as usual nobody answered the blasted question. I can think of any number of scenarios that require bounds determination. For example, displaying HTML can be done with an IFRAME in the host HTML page, and being able to position it according to the rendered bounds of a panel would allow you to integrate it nicely into your UI.

虽然其他人已经满足了这种需要,但通常没人会回答这个抨击问题。我可以想到任何需要边界确定的场景。例如,可以使用主机HTML页面中的IFRAME显示HTML,并且能够根据面板的渲染边界定位它,这样您就可以很好地将其集成到UI中。

You can determine the origin of a control using a GeneralTransform on Point(0,0) to the root visual coordinate system, and ActualHeight and ActualWidth are surfaced directly.

您可以使用Point(0,0)上的GeneralTransform到根视觉坐标系来确定控件的原点,并直接浮出ActualHeight和ActualWidth。

GeneralTransform gt = 
  TransformToVisual(Application.Current.RootVisual as UIElement);
Point offset = gt.Transform(new Point(-1, -1));
myFrame.SetStyleAttribute("width", (ActualWidth + 2).ToString());
myFrame.SetStyleAttribute("height", (ActualHeight + 2).ToString());
myFrame.SetStyleAttribute("left", offset.X.ToString());
myFrame.SetStyleAttribute("top", offset.Y.ToString());
myFrame.SetStyleAttribute("visibility", "visible");

In the sample above I have transformed (-1, -1) and added 2 to both height and width to compensate for the single pixel border region around an IFRAME - this code is lifted from a working application that uses an IFRAME to render "embedded" HTML when browser hosted.

在上面的示例中,我已经转换了(-1,-1)并在高度和宽度上添加了2以补偿IFRAME周围的单个像素边界区域 - 此代码从使用IFRAME呈现“嵌入”的工作应用程序中解除“浏览器托管时的HTML。

Also, there's more than one way to skin a cat and for hit testing you may find VisualTreeHelper interesting.

此外,有一种方法可以让猫皮肤受到攻击,对于热门测试,您可能会发现VisualTreeHelper很有趣。

IEnumerable<UIElement> VisualTreeHelper
  .FindElementsInHostCoordinates(Point intersectingPoint, UIElement subtree)

This returns every UIElement under a point (typically from the mouse). There is an overload that takes a Rect instead.

这将返回一个点下的每个UIElement(通常来自鼠标)。有一个重载需要一个Rect。

#3


1  

you can traverse your controls by VisualTreeHelper and see if the cursor in the element by VisualTreeHelper.HitTest(...) method

你可以通过VisualTreeHelper遍历你的控件,并通过VisualTreeHelper.HitTest(...)方法查看元素中的光标

#1


3  

Why don't you just test the IsMouseOver or IsMouseDirectlyOver properties ?

为什么不直接测试IsMouseOver或IsMouseDirectlyOver属性?

#2


5  

Although others have met the need, as usual nobody answered the blasted question. I can think of any number of scenarios that require bounds determination. For example, displaying HTML can be done with an IFRAME in the host HTML page, and being able to position it according to the rendered bounds of a panel would allow you to integrate it nicely into your UI.

虽然其他人已经满足了这种需要,但通常没人会回答这个抨击问题。我可以想到任何需要边界确定的场景。例如,可以使用主机HTML页面中的IFRAME显示HTML,并且能够根据面板的渲染边界定位它,这样您就可以很好地将其集成到UI中。

You can determine the origin of a control using a GeneralTransform on Point(0,0) to the root visual coordinate system, and ActualHeight and ActualWidth are surfaced directly.

您可以使用Point(0,0)上的GeneralTransform到根视觉坐标系来确定控件的原点,并直接浮出ActualHeight和ActualWidth。

GeneralTransform gt = 
  TransformToVisual(Application.Current.RootVisual as UIElement);
Point offset = gt.Transform(new Point(-1, -1));
myFrame.SetStyleAttribute("width", (ActualWidth + 2).ToString());
myFrame.SetStyleAttribute("height", (ActualHeight + 2).ToString());
myFrame.SetStyleAttribute("left", offset.X.ToString());
myFrame.SetStyleAttribute("top", offset.Y.ToString());
myFrame.SetStyleAttribute("visibility", "visible");

In the sample above I have transformed (-1, -1) and added 2 to both height and width to compensate for the single pixel border region around an IFRAME - this code is lifted from a working application that uses an IFRAME to render "embedded" HTML when browser hosted.

在上面的示例中,我已经转换了(-1,-1)并在高度和宽度上添加了2以补偿IFRAME周围的单个像素边界区域 - 此代码从使用IFRAME呈现“嵌入”的工作应用程序中解除“浏览器托管时的HTML。

Also, there's more than one way to skin a cat and for hit testing you may find VisualTreeHelper interesting.

此外,有一种方法可以让猫皮肤受到攻击,对于热门测试,您可能会发现VisualTreeHelper很有趣。

IEnumerable<UIElement> VisualTreeHelper
  .FindElementsInHostCoordinates(Point intersectingPoint, UIElement subtree)

This returns every UIElement under a point (typically from the mouse). There is an overload that takes a Rect instead.

这将返回一个点下的每个UIElement(通常来自鼠标)。有一个重载需要一个Rect。

#3


1  

you can traverse your controls by VisualTreeHelper and see if the cursor in the element by VisualTreeHelper.HitTest(...) method

你可以通过VisualTreeHelper遍历你的控件,并通过VisualTreeHelper.HitTest(...)方法查看元素中的光标