The more I work with Windows Presentation Foundation (WPF), the more I'm impressed with its consistency. I'm finding it so intuitive to navigate, and just plain fun to use. The other day I was trying to build something that behaved similarly to an ASP.NET repeater control. I wanted to use a data template to specify the presentation of each item, and I wanted the list of items to be presented using a WrapPanel. Pretty simple, you'd think!
When the result of my efforts looked like stretched silly putty, I figured that I must have taken the wrong approach, so I hooked up with the author of our WPF short course, Ian Griffiths. Ian reminded me about constraints in layout, and I was able to fix my problem pretty quickly.
Unless you use absolute positioning (such as the Canvas layout control does), WPF uses a pretty sophisticated negotiation model to figure out how each control will be laid out. WrapPanel, for example, asks each child element how much space it wants, and lays those children out in a wrapped fashion. Here's a simple example with two buttons:
| <WrapPanel> <Button>One</Button> <Button>Two</Button> </WrapPanel> | |
In the above case, the WrapPanel asks its children how much space they want. The buttons size themselves according to their content (in the example above, the text in each button determines its size). So there's no problem. But try dropping a simple Image into the same panel and things start to get weird:
| <WrapPanel> <Button>One</Button> <Image Source="..."/> </WrapPanel> | |
You see, by default, Image stretches to fill the available space in the container. But the WrapPanel isn't constraining the child's space, and so things get strange. Either the parent or the child in this case needs to step up and figure out how much space should be allotted for the child. One easy way to fix this is to turn off stretching in the Image element:
| <WrapPanel> <Button>One</Button> <Image Source="..." Stretch="None"/> </WrapPanel> | |
Now I've got something more reasonable - the little XML image is the size I expected it to be. Image is an example of a control that can wreak havoc with the layout engine if you're not aware of this. ScrollViewer is an example of a container that can do the same thing, as it essentially tells its children they have infinite space. So if you run into weirdness like this, take some time to adjust various constraints until you find a solution you like!





