在 WPF 表单中从画布获取 UI 元素大小

4

我像这样在画布上实例化新的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} 

为什么我可以获取画布上物品的位置,但无法获取其大小?

BannerImage类由什么组成? - dhilmathy
@dhilmathy 这只是一个带有文本块和标签的画布。 - lost9123193
2
没有名为 BannerImage.NET 类,这意味着它是由您定义的类。因此,除非我们知道像 DesiredSizeMeasure() 这样的方法/属性是做什么的,否则无法回答您的问题。 - Sach
@Sach BannerImage 是一个画布,因此我可以调用那些方法。 - lost9123193
1
你在控件中实现了MeasureOverride吗?我相信默认情况下,Canvas将返回0作为其所需大小,因为它会根据所告知的大小进行调整。由于你在派生的Canvas中有子控件,你需要找出你需要的大小并返回它。 - pstrjds
1个回答

3
我猜测您没有重写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);
}

我意识到在评论中解释了问题,但没有将其添加到我的答案中。您无法获取大小的原因是必须在派生类中提供一个覆盖来计算它。默认情况下,Canvas返回0的DesiredSize,因为它将适应分配给它的任何大小。在您的派生控件的情况下,您有一个Canvas作为基类,但已经添加了其他控件。如果不提供 MeasureOverride方法的覆盖,则只调用基本实现(由Canvas实现的方法)。基本Canvas不知道您的控件大小要求。您可能还需要覆盖 ArrangeOverride这篇文章提供了两种方法的相当好的解释,它们的作用以及为什么需要覆盖它们。它还提供了两种方法的示例。

好的,谢谢。我会研究一下这个问题。我的所有元素都是画布(Canvas)。所以我一直在使用Canvas.Add(element)。我会尝试一下这个方法。 - lost9123193
感谢您的解释。我需要进行配置,但我认为这是正确的方向。 - lost9123193

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接