Welcome to irritatedVowel.com Sign in | Help

POKE 53280,0: Pete Brown's Blog

Silverlight, WPF, Windows Client Development, Woodworking, .NET Programming, CNC, Nature, and other topics.

Subscribe

Subscribe to my feed
Add to Technorati Favorites

My Book

Order my upcoming book, Silverlight in Action, covering Silverlight 4, ViewModel/MVVM, WCF RIA Services, MEF and more

About Pete Brown

Pete Brown is a Microsoft Developer Division Community Program Manager, focusing on Windows Client Development as well as a former Microsoft Silverlight MVP and INETA Speaker. Pete writes on a number of topics including Silverlight, WPF, .NET, woodworking and working as a consultant in the DC area. read more

Community Events


who's online

AddThis Social Bookmark Button

Creating a Silverlight Control that Stays Square

I had a dumb design problem today. I wanted an ellipse to be inside a grid, but centered vertically and horizontally, and with a 1:1 aspect ratio. I want a circle, centered in a cell. I could get it sized correctly, but the minute I set VerticalAlignment, it would disappear unless I set it to UniformToFill rather than Uniform. Checking it out, the size was undefined. No other panels/containers seemed to help. I verified that this behavior also happens in WPF, so I assume it is a by-design thing.

Problem is, at design time, I don’t know what the width and height will be, and didn’t want to have to write code to handle resizing it with some hard-coded behavior that walks the tree looking for a named element in a particular template. It needed to be designer-friendly.

So I wrote a little content control (a control that can hold one other element in Silverlight) that will stay square and make its contents fill the container. I haven’t tested it outside of my particular scenario, but thought you might be interested. The code is dead simple:

// This container will maintain a square aspect ratio
public class SquareContainer : ContentControl
{
    private Size CalculateMaxSize(Size availableSize)
    {
        double maxDimension = Math.Min(availableSize.Height, 
                                        availableSize.Width);

        Size maxSize = new Size(maxDimension, maxDimension);

        return maxSize;
    }

    protected override Size MeasureOverride(Size availableSize)
    {
        Size maxSize = CalculateMaxSize(availableSize);

        if (Content != null && Content is FrameworkElement)
        {
            ((FrameworkElement)Content).Measure(maxSize);
        }

        return maxSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        Size maxSize = CalculateMaxSize(finalSize);

        if (Content != null && Content is FrameworkElement)
        {
            ((FrameworkElement)Content).Arrange(   
                            new Rect(new Point(0, 0), maxSize));
        }

        return maxSize;
    }
}

The markup is also pretty simple. Just point the xmlns:local to the assembly where this control resides.

<local:SquareContainer x:Name="OverlayContainer"
                       VerticalAlignment="Center"
                       Margin="14">
    <Ellipse Stroke="Black"
             StrokeThickness="1"
             Stretch="Uniform"
             >
        <Ellipse.Fill>
            <RadialGradientBrush>
                <GradientStop Offset="0" Color="#BBFFFFFF" />
                <GradientStop Offset="1" Color="#00FFFFFF" />
            </RadialGradientBrush>
        </Ellipse.Fill>
    </Ellipse>
</local:SquareContainer>

Hope this helps solve a problem for you some day :)

UPDATE: Just updated the code so the control worked a little better. Also, I need to caution you against nesting the SquareContainer. If you do, and you cause a bunch of changes (by resizing the browser a lot, for example, you end up with what is likely a stack overflow or similar and the browser will just die. I’ll work to fix that, but wanted to make sure you were aware of the limitation.

  Add to Technorati Favorites
Posted: Friday, January 09, 2009 7:38 PM by Pete.Brown
Filed under: ,

Comments

Christopher Steen said:

Link Listing - January 10, 2009
# January 10, 2009 9:34 AM

Christopher Steen said:

Code Camps First New Hampshire Code Camp on February 28th [Via: cbowen ] Link Collections Interesting...
# January 10, 2009 9:35 AM

Community Blogs said:

In this issue: Michael Washington, Pete Brown(2), Shawn Wildermuth(2), Jesse Liberty, Mike Snow, Terence
# January 10, 2009 9:06 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Enter the text you see in the image:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS