WPF: Can I get the size of a UIElement AFTER a transform is applied?

被刻印的时光 ゝ 提交于 2019-12-24 04:54:26

问题


In WPF/Silverlight, can I get the calculated value of a UIElement after a transformation is applied?

(Per the comment below):

I've got a stack panel and I've applied a TranformGroup to it. There are two translate and one scale transforms in this group.

(warning, psuedo code ahead)

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

Obviously the scale transform is the one I'm most interested in.


回答1:


Matthew, as you pointed out ActualWidth and ActualHeight don't change if you apply transforms. ActualWidth and ActualHeight represent the calculated width/height after the layout system has finished calculating the size of a control (based on values such as Margin, HorizontalAlignment, etc.)

One way to get the size of a control taking into account all of the scale transformations that have been applied to it is to walk up the visual tree and apply all scale transforms to the ActualWidth and ActualHeight of a control:

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;
}

Keep in mind that this might be inefficient if your visual tree is deep or you perform this many times. In practice I've never run into any problems with this, however.




回答2:


you could simply apply the transform:

control.LayoutTransform.Transform(new Point(0,0))




回答3:


Yes, you can check ActualWidth and ActualHeight on any FrameworkElement to figure this out. You'll need to check whether it is visible though if you have elements that hide.

If you want to know after the control has loaded use the Loaded event.



来源:https://stackoverflow.com/questions/1169589/wpf-can-i-get-the-size-of-a-uielement-after-a-transform-is-applied

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!