WPF使用TransformToAncestor获取元素的相对坐标

原理: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

https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.media.visual.transformtoancestor?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DZH-CN%26k%3Dk(System.Windows.Media.Visual.TransformToAncestor);k(SolutionItemsProject);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.0);k(DevLang-csharp)%26rd%3Dtrue&view=netframework-4.8

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值