在 WPF/Silverlight 中,我可以在应用转换后获取 UIElement
的计算值吗?
(根据下面的评论):
我有一个堆栈面板,并对其应用了 TranformGroup
。该组中有两个平移和一个缩放变换。
(警告,前面有伪代码)
groupTransform.children.add(new TranslateTransform());
groupTransform.children.add(new ScaleTransform());
groupTransform.children.add(new TranslateTransform());
containerToScale.RenderTransform = groupTransform;
...
// code that sets values to all the transforms
显然,比例变换是我最感兴趣的。
最佳答案
马修,正如你所指出的ActualWidth
和ActualHeight
如果应用变换,则不要更改。 ActualWidth
和ActualHeight
表示布局系统完成计算控件大小后计算出的宽度/高度(基于 Margin
、 HorizontalAlignment
等值)
考虑到已应用于控件的所有比例变换来获取控件大小的一种方法是沿着可视化树向上并将所有比例变换应用于 ActualWidth
和ActualHeight
控件的:
public static Size GetActualSize(FrameworkElement control)
{
Size startSize = new Size(control.ActualWidth, control.ActualHeight);
// go up parent tree until reaching root
var parent = LogicalTreeHelper.GetParent(control);
while(parent != null && parent as FrameworkElement != null && parent.GetType() != typeof(Window))
{
// try to find a scale transform
FrameworkElement fp = parent as FrameworkElement;
ScaleTransform scale = FindScaleTransform(fp.RenderTransform);
if(scale != null)
{
startSize.Width *= scale.ScaleX;
startSize.Height *= scale.ScaleY;
}
parent = LogicalTreeHelper.GetParent(parent);
}
// return new size
return startSize;
}
public static ScaleTransform FindScaleTransform(Transform hayStack)
{
if(hayStack is ScaleTransform)
{
return (ScaleTransform) hayStack;
}
if(hayStack is TransformGroup)
{
TransformGroup group = hayStack as TransformGroup;
foreach (var child in group.Children)
{
if(child is ScaleTransform)
{
return (ScaleTransform) child;
}
}
}
return null;
}
请记住,如果您的视觉树很深或者您多次执行此操作,这可能会效率低下。然而,在实践中我从未遇到过任何问题。
关于WPF:应用转换后我可以获取 UIElement 的大小吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1169589/