代码之家  ›  专栏  ›  技术社区  ›  lost9123193

在wpf表单中从画布获取ui元素大小

  •  4
  • lost9123193  · 技术社区  · 6 年前

    我将新的ui元素实例化到画布上,如下所示:

    public class MainForm :Canvas 
    {
        List<BannerImage> bannerList;
    
        AddImages()
        {
            bannerImage = new BannerImage("title", "content");
            //accompanied with animation
            Children.Add(bannerImage);
            bannerList.Add(bannerImage);
        }
    

    我需要打电话给Bannerimages才能得到他们现在的位置,下面的工作:

    foreach(bannerItem in bannerList)
    {
       double rightPosition = Canvas.GetRight(bannerItem);
    }
    

    但我不能这样做:

    bannerItem.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity) 
    Size s = bannerItem.DesiredSize;
    

    结果总是

    {0,0} 
    

    为什么我能在画布上找到物品的位置而不是尺寸?

    1 回复  |  直到 6 年前
        1
  •  2
  •   pstrjds    6 年前

    我只是猜测你没有超限 MeasureOverride 是的。我将提供一个基本的实现,假设每个元素都是堆叠的,但是您需要修改它,以考虑到您的子控件以及您可能创建的自定义布局(我不知道它们是否在网格中、水平堆叠、某种滚动容器中等)。

    protected override Size MeasureOverride(Size availableSize)
    {
        var height = 0.0;
        var width = 0.0;
    
        foreach (UIElement child in InternalChildren)
        {
            child.Measure(availableSize);
            if (child.DesiredSize.Width > width) width = child.DesiredSize.Width;
            height += child.DesiredSize.Height;
        }
    
        width = double.IsPositiveInfinity(availableSize.Width) ? width : Math.Min(width, availableSize.Width);
        height = double.IsPositiveInfinity(availableSize.Height) ? height : Math.Min(height, availableSize.Height); 
    
        return new Size(width, height);
    }
    

    编辑
    我意识到我在评论中解释了这个问题,但没有把它加入我的回答中。你的原因 can't get the size 因为必须在派生类中提供重写才能计算它。默认情况下,canvas返回 DesiredSize 因为它将适应分配给它的任何大小。对于派生控件,您有一个 Canvas 作为基类,但您已向其添加了其他控件。如果不提供 MeasureOverride 方法,然后是基方法(由 帆布 )是唯一一个被调用的。基地 帆布 对控件的大小要求一无所知。你可能还需要重写 ArrangeOverride 是的。 This article 对这两种方法、它们的作用以及为什么需要重写它们提供了很好的解释。它还提供了这两种方法的示例。