WPF 获取元素相对位置的方法
在Canvas中,我们可以为它的子元素通过附加属性Canvas.Left和Canvas.Top来设置位置,那么子元素和Canvas之间的位置关系也就很清楚了,但是我们需要更一般化的方法,来获得某个子元素相对于桌面,某个父元素等的位置关系,那就需要引入Transform的概念了,也就是通过这个数学化的概念来达到我们想到达的目的。当然除了这个,还有计算的函数,那就是来自Visual的TransformToVisual(Visual visual)方法,在该方法的MSDN文档中有这样一个例子:
XAML代码:
?
?
?核心代码:
?
// Return the general transform for the specified visual object.GeneralTransform generalTransform1 = myStackPanel.TransformToVisual(myTextBlock);// Retrieve the point value relative to the child.Point currentPoint = generalTransform1.Transform(new Point(0, 0));?
?
先说一下这个例子的目的是,求得myStackPanel相对于它的子元素myTextBlock的位置,我们可以猜想,若以myTextBlock的左上角为(0,0),那么算上Margin值,这个相对的位置应该是(-4,-4)。
现在看代码,首先,使用myStackPanel.TransformToVisual获得一个用于封装Transform概念的GeneralTransform对象,这是个抽象的通用类,我们可以看一下它的继承关系:
?
?
?
Object
?????DispatcherObject?(abstract)
????????????DependencyObject
???????????????????Freezable?(abstract)
??????????????????????????Animatable?(abstract)
?????????????????????????????????GeneralTransform?(abstract)
????????????????????????????????????????GeneralTransformGroup
?????????????????????????????????Transform?(abstract)
???????????????????????????????????????TranslateTransform
???????????????????????????????????????ScaleTransform
???????????????????????????????????????SkewTransform
???????????????????????????????????????RotateTransform
???????????????????????????????????????MatrixTransform
???????????????????????????????????????TransformGroup?
?
我通过断点,发现它返回的是一个MatrixTransform类型,这就好办了,因为它们的内部都含有一个Matrix属性,用来表示Visual的Transform状况,看其中的值,就是{1,0,0,1,-4,-4},其实就是如下的一个矩阵:
|1 ? ?0 ? 0|
|0 ? ?1 ? 0|
|-4 ?-4 ? 1|
最后一列是固定的,所以省去,按行展开,就是{1,0,0,1,-4,-4}。我们知道这个3乘以3矩阵的每个元素的作用,最后一行的前两列用于表示位移,那么,用(0,0)乘以这个矩阵后得出的点是哪个点呢(自己算算就明白,其实这里就是平移产生效果),若你懒点,就直接用Transform方法,它会帮助我们得到这个结果,那就是把我们的点Point(0,0)放进去即可,得出的点就是(-4,-4)。
?