I’ve often been asked the question of when should we use a Canvas and when a Single Celled Grid….
This is a snapshot of the an MSDN article . Our inputs are marked as [Cennest:]. The source can be read at http://msdn.microsoft.com/en-us/magazine/ff646962.aspx
A single-cell Grid is just like a regular Grid except without any row or column definitions. If the Grid has only one cell, you can put multiple elements into the Grid cell and you don’t use any of the Grid’s attached properties to indicate rows or columns.
Initially, using a Canvas or a single-cell Grid seems very similar. Regardless which one you use for vector graphics, Line, Polyline, Polygon and Path elements will be positioned relative to the upper-left corner of the container based on their coordinate points.
The difference between the Canvas and the single-cell Grid is in how the container appears to the rest of the layout system. WPF and Silverlight incorporate a two-pass, top-down layout where every element interrogates the size of its children and is then responsible for arranging its children relative to itself. Within this layout system, the Canvas and the single-cell Grid are very different:
- To its children, the Grid has the same dimensions as the dimensions of its own parent. These are usually finite dimensions, but the Canvas always appears to have infinite dimensions to its children.* The Grid reports the composite size of its children to its parent. However, the Canvas always has an apparent size of zero, regardless of the children it contains.
[Cennest:- This has an impact when you try to put the canvas in a Scrollviewer and think that the ScrollViewer will automatically show Scrollbars if the canvas starts exceeding the height and width. However you are zapped when the scroll bars just don’t show up…this is because the canvas notified its height and width as 0 to the scrollviewer which then happily did not show any scrollbars!!.
A workaround for this if you still want to use the scrollbar is to create a Custom Canvas control and override its MeasureOverride property. See this sample]
Suppose you have a bunch of Polygon elements that form some kind of cartoon-like vector graphics image. If you put all these Polygon elements in a single-cell Grid, the size of the Grid is based on the maximum horizontal and vertical coordinates of the polygons. The Grid can then be treated as a normal finite-sized element within the layout system because its size properly reflects the size of the composite image. (Actually, this works correctly only if the upper-left corner of the image is at the point (0, 0), and there are no negative coordinates.)
Put all those polygons in a Canvas, however, and the Canvas reports to the layout system that it has a size of zero. In general, when integrating a composite vector graphics image into your application, you almost certainly want the behavior of the single-cell Grid rather than the Canvas.
So is the Canvas entirely useless? Not at all. The trick is to use the peculiarities of the Canvas to your advantage. In a very real sense, the Canvas doesn’t participate in layout. Hence, you can use it whenever you need to transcend layout—to display graphics that break the bounds of the layout system and float outside it. By default the Canvas doesn’t clip its children, so even if it is very small, it can still host children outside its bounds. The Canvas is more of a reference point for displaying elements or graphics than it is a container
Hope this makes things a bit clearer!
Till next time!
Cennest!