lost9123193
lost9123193

Reputation: 11040

Get UI element Size from Canvas in WPF Forms

I instantiate new Ui elements onto a canvas like so:

public class MainForm :Canvas 
{
    List<BannerImage> bannerList;

    AddImages()
    {
        bannerImage = new BannerImage("title", "content");
        //accompanied with animation
        Children.Add(bannerImage);
        bannerList.Add(bannerImage);
    }

I need to call the bannerImages to get their current position, the following works:

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

But I can't do the following:

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

Which always ends up to be

{0,0} 

Why is it that I can get the position of the item on the canvas but not the size?

Upvotes: 4

Views: 468

Answers (1)

pstrjds
pstrjds

Reputation: 17448

I am just going to take a guess that you didn't override MeasureOverride. I will provide a basic implementation assuming that each element is stacked, but you would need to modify it to take into consideration your child controls and what ever custom layout you may have created (I don't know if they are in a grid, horizontally stacked, in a some kind of scrolled container, etc).

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

Edit
I realized that I explained the issue in a comment, but didn't add it into my answer. The reason you can't get the size is because you have to provide an override in your derived class to compute it. By default, Canvas returns a DesiredSize of 0 since it will adapt to whatever size is assigned to it. In the case of your derived control, you have a Canvas as the base class but you have added additional controls to it. If you don't provide an override of the MeasureOverride method, then the base one (the one implemented by Canvas) is the only one that is called. The base Canvas knows nothing of your controls size requirements. You probably also will need to override ArrangeOverride. This article provides a pretty good explanation about the two methods, what they do and why you need to override them. It also provides and example of both methods.

Upvotes: 3

Related Questions