WPF:应用转换后我可以获取 UIElement 的大小吗?

发布于 2024-07-29 10:56:13 字数 495 浏览 7 评论 0原文

在 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

显然比例变换是我最感兴趣的。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

辞取 2024-08-05 10:56:13

马修,正如您所指出的,如果您应用变换,ActualWidthActualHeight 不会改变。 ActualWidthActualHeight 表示布局系统完成计算控件大小后计算出的宽度/高度(基于诸如 Margin 等值, Horizo​​ntalAlignment 等)

考虑已应用于控件的所有比例变换来获取控件大小的一种方法是沿着可视化树向上并将所有比例变换应用于 <控件的 code>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;
}

请记住,如果您的可视化树很深或者执行多次,这可能会效率低下。 然而,在实践中我从未遇到过任何问题。

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.

离鸿 2024-08-05 10:56:13

您可以简单地应用变换:

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

you could simply apply the transform:

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

南风起 2024-08-05 10:56:13

是的,您可以检查任何 FrameworkElement 上的 ActualWidthActualHeight 来弄清楚这一点。 如果您有隐藏的元素,您需要检查它是否可见。

如果您想知道控件加载后的情况,请使用 Loaded 事件。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文