Canvas is a useful to implement absolute positioning of UI elements and provides a
ZIndex property to define their rendering order as well. However, sometimes such a property would be useful in other
Panels as well.
For example, consider a
Grid as follows:
Although it is natural from the logical standpoint to have the title
TextBlock as the first child of the
Grid, the result will be the following:
The title text is nowhere to be seen! The reason for that is the
Image is stretching across the whole
Grid and as it is rendered second, it covers the
TextBlock. Usually, this is when we switch the order of children:
This works well. The title text is rendered after the image, so it is above it. However, this benefit brought one disadvantage – the “reading order” of the code is mixed up.
Luckily, this is where
Canvas.ZIndex comes in. Surprisingly, this attached dependency property does not apply only to
Canvas, but also to other
Panel derived classes, including
Grid. Let’s see what happens when we do this:
We set the
Canvas.ZIndex attached property on our
TextBlock to 10. The result now looks just as we expect:
TextBlock is the first child of the
Grid, thanks to its positive
Canvas.ZIndex value, it now renders above the “background” image. The
Canvas.ZIndex property can be used in any
Panel-derived class to adjust the rendering order. The default value is zero, and higher value means the control is rendered later. Finally, when two control’s
ZIndex value is tied, the XAML-declaration order determines the rendering order.
Personally, I didn’t know about this trick until I saw the template of WinUI
NavigationView control, which uses it to render the navigation pane button grid above the content (see here on GitHub), while preserving the “logical” reading order of XAML. Very cool!
What about WPF?
In WPF, the
ZIndex property is declared directly on the
Panel class, which actually makes the trick clearer:
What about Uno Platform?
ZIndex property is not yet supported in non-
Canvas panels. However, there is an open issue for this already – Add support for Canvas.ZIndex in any Panel · Issue #325. If you would like to see this supported, vote on this issue and it will surely be addressed soon!
Sample source code for this article is available on my GitHub.