原理:WPF的界面元素是由Visual元素构成的。在可视元素树Visual中,获取某个元素相对于它的父级元素(Ancestor)的坐标,可以使用TransformToAncestor与Transform方法。
指定中心点,获取相对坐标
例子一:确定TextBlock相对于窗体的位置
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<StackPanel Margin="16">
<StackPanel Margin="8">
<TextBlock Name="myTextBlock" Margin="4" Text="Hello, world" />
</StackPanel>
</StackPanel>
</Window>
// Return the general transform for the specified visual object.
GeneralTransform generalTransform1 = myTextBlock.TransformToAncestor(this);
// Retrieve the point value relative to the parent.
Point currentPoint = generalTransform1.Transform(new Point(0, 0));//窗体位置为(0,0)
例子二:获取Button的中心点,相对于Canvas的位置
<Window x:Class="测试相对坐标与绝对坐标.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:测试相对坐标与绝对坐标"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Canvas Name="myCanvas">
<Button Width="100"
Name="myButton"
Click="MyButton_Click"
Height=" 100"
Content="我是按钮"
Canvas.Left="100"
Canvas.Top="100"/>
</Canvas>
</Window>
private void MyButton_Click(object sender, RoutedEventArgs e)
{
Point current = new Point();
current= this.myButton.TransformToAncestor(this.myCanvas)
.Transform(new Point(myButton.Width/2, myButton.Height/2));//获取中心点的位置
MessageBox.Show(current.X.ToString() + " "+ current.Y.ToString ());
}
获取相对于屏幕的坐标
Point controlPoint = new Point(0, 0);
controlPoint = ((TextBox)sender).PointToScreen(controlPoint);//获取控件相对于屏幕的位置
mkeyBoard.Top = controlPoint.Y + ((TextBox)sender).ActualHeight;
mkeyBoard.Left = controlPoint.X-20;
获得子元素相对于父元素位置和宽高
<Canvas x:Name="cv">
<Rectangle x:Name="rct" Width="100" Height="80" Fill="#FFD62525" Canvas.Left="309" Canvas.Top="181" />
</Canvas>
后台C#
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Rect itemRect = VisualTreeHelper.GetDescendantBounds(rct);//itemRect是0,0,100,80
Rect itemBounds = rct.TransformToAncestor(cv).TransformBounds(itemRect);// itemBounds是309,181,100,80
Console.WriteLine(itemRect);
Console.WriteLine(itemBounds);
}
参考
http://www.ayjs.net/post/757.html