Mark Wilson-Thomas is our resident WPF Layout expert and is leveraging my blog to get some great information out about how the VS 2008 WPF Designer approaches layout:
How to get the best out of the WPF designer when laying out your WPF app
Lots of folks have asked what the reasoning is for the WPF designer giving a new control instance on the design surface a width and height, and margins so that it stays where you drop it and sizes to a reasonable default size. The story of “why we emit margins to make things feel like anchored controls in Windows Forms” by default in the Cider layout system is really about making it possible to traverse two paths to your final layout, and to cross over from one to the other:
Path 1: This is the popular “Visual Place-and-size” path that people have been used to on practically every GUI designer that’s shipped since Visual Basic.
Path 2: This is the “Container first” path, where you lay out the Grid(s) or other containers that will govern the layout, then place controls inside them (generally with zero margin) and let the container take care of the resize behavior for you
Path 2 is an approach I’ve seen advocated in several posts and discussions on the topic. Both from a “WPF platform-purist” point of view and an experienced Web UI developers point of view, I agree this a clear and straightforward way of thinking about layout in WPF. However if you’re one of the many millions of developers who have been working with Windows Forms, VB, etc for years, and have never built a web app, it will probably not be an easy transition for you to be forced to start thinking this way for your first app building experiences – and in addition, you may never want to build a fully resizable app.
So if you’re a developer with that set of experience, what we let you do is get a pretty much functional WPF app in the traditional way you always have using path 1 (and actually for a lot of applications you might even stop there). If you wish to, we then give you help to start dropping gridlines into your design and snapping them to your controls/your controls to them (getting the zero margins you are looking for) ready to move into Auto-layout-land. Unfortunately, we didn’t have time on Cider v1 to deliver the full set of features that would give you the “flip-to-auto” part of the story on the design surface, so you have to go to XAML or the property inspector to make it happen, and when you do the behavior of the design surface can become a little “quirky” in places.
So, what’s the best path for getting great layout in the designer then?
The application layout path that works best right now if you want to use the WPF design surface is:
- Place your controls and get them roughly where you want them in your outermost grid
- Drop in your gridlines to control resize behavior but don’t start switching your grid rows/columns and controls into Auto sizing yet
- Snap your controls to the gridlines to zero out margins where that’s what you want (or multi-select your controls in the property inspector and zero margins on the whole set of selected controls’ margins)
- When everything’s done, flip your controls and grid rows/columns as appropriate into auto-sizing using XAML or the PI.
NOTE 1: If you need to move/resize things after this step, it’s best to flip back out of auto first.
NOTE 2: Steps 1 & 2 are pretty much interchangeable
Why doesn’t the designer favor auto layouts by default?
I think it’s reasonable to argue we should have started with a mode that favored auto layouts by placing new controls with no margins in whatever container they were added to (rather than the method we have used) by default. However after many discussions in the team we felt this kind of total break with the past for our default experience would be just too jarring for too many existing UI technology users.
I do think that a designer setting that allowed you to have a more “start with auto” approach would be a useful feature, and we’ll think about that for future releases. As an aside, right now one way to work in a “start with auto” approach should you wish to do so, is to work entirely in the XAML editor and not use the toolbox for control creation at all. That way you will get only the properties you explicitly wanted at creation time.