Introduction
The TilePanel
is a WPF Panel similar to a WrapPanel
that wraps its content by placing the items at the topmost position in the control.
This is useful when displaying a collection of different sized objects and the collection order is not important.
The Panel also respects the Orientation
property for wrapping either
horizontally or vertically.
Background
The background to this article stems from a project I am currently working on which requires that a collection of UserControls be embedded into a layout panel.
The UserControls are all instrument panels which can vary in size from 100x100 units to 400x400 units in different shapes. When these were laid out with a
WrapPanel
,
large horizontal gaps were left if different sized objects were positioned next to each other.
This led me to look to see if I could tile the UserControls so that smaller objects could stack ontop of each other to fill the space generated by a larger object.
The TilePanel
is my initial solution.
Using the code
The supplied code is separated into two projects, TilePanel and TilePanelTest.
TilePanel
comprises of a single source module TilePanel.cs containing the TilePanel
control derived from
Panel
. TilePanel
derives from Panel
and overrides
Panel
's ArrangeOverride
and MeasureOverride
methods.
TilePanel
also provides an Orientation
property to orient the control in a vertical or horizontal mode.
TilePanelTest is a test application showing how to use the TilePanel
.
The following code snippet shows the best way to use this control
The code snippet shows an ItemsControl
bound to the TestCollection
collection. This supplies the list of objects to be displayed.
To put all the items into the TilePanel
, set the TilePanel
as the
ItemsControl.ItemsPanel
and set the orientation of TilePanel
, in this case to
Vertical
.
To make the TilePanel
useful, it needs to have the plane opposite to it's orientation a fixed size so that it will wrap. This has been done in the code snippet by enclosing the
ItemsControl
in a
ScrollViewer
with the vertical scroll bar enabled and the horizontal
scroll bar disabled. This allows the TilePanel
to wrap in the horizontal direction and fill in the vertical direction with a
scroll bar to scroll the panel.
Two further properties AlignmentBoundary
and
AlignOnLesserEdge
have beed added to control whether content at similar vertical positions should be aligned to improve layout look and spacial use
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" >
<ItemsControl ItemsSource="{Binding TestCollection}" Margin="10" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<TilePanel:TilePanel Background="Beige" Orientation="Vertical" AlignmentBoundary="10" AlignOnLesserEdge="false"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
...
History
v1.01
Revised the original to fix a bug in the layout algorithm. This led me to review the layout algorithm with respect to the condition where two 'edges' are close to each other and what should occur under this circumstance. The new algorithm applies a boundary condition whereby if two edges are close together and overlap then the lower edge is raised to the same level as the higher edge. At the same time, boundary conditions may differ depending upon the left and right alignment of the similar edges.
Consequently I have added two properties AlignmentBoundary
and
AlignOnLesserEdge
to control the boundary size and alignment mode for the lesser edge.