Circular Panel
A layout panel that places its children round a circle or an ellipse – evenly round the whole ring, or fanned across part of it – and can turn the ring to any angle.
Assembly
| Assembly | Binarymission.WPF.Controls.CircularPanel.dll |
| Root namespace | Binarymission.WPF.Controls.Panels |
| Target frameworks | .NET Framework 4.8, .NET 6 / 8 / 10 |
Overview
Use it for radial menus, a ring of shortcuts round a central picture, the hours on a clock
face, seats round a table plan, or a carousel-like ring of thumbnails that turns when
RenderAngle is animated. It works as a panel in its own right or, through
ItemsControl.ItemsPanel, as the layout of any bound list.
The ring
The ring is centred in the panel and follows its shape: an ellipse whose horizontal radius is
the panel's width divided by ItemsClosenessFactor and whose vertical radius is its
height divided by the same factor. A square panel gives a circle. The ring grows and shrinks as the
panel is resized.
Placing the items
Each child keeps the size it asks for and is centred on its point on the ring; the panel never
squeezes a child to fit. The first child sits at RenderAngle, measured in radians
clockwise from the right-hand side of the ring, and each child after it one gap further round. The
gap depends on AngleCalculationStrategy: with
GapAngleCalculationStrategy.Dynamic the children share the whole circle equally, and
with GapAngleCalculationStrategy.Custom they share the angle in
ItemsGapAngleFactor.
Size
The panel takes all the room it is offered. Where it is offered unlimited room – in a
StackPanel, say, or an auto-sized row – it asks for enough for its largest child to
fit on the ring. It does not clip: an item placed past the edge is still drawn, unless a container
round the panel clips it.
Getting started
Eight department shortcuts round a circle, the first at the top.
<Window x:Class="Intranet.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:panels="clr-namespace:Binarymission.WPF.Controls.Panels;assembly=Binarymission.WPF.Controls.CircularPanel"
Title="Departments" Width="520" Height="520">
<panels:CircularPanel Width="440" Height="440"
ItemsClosenessFactor="2.6"
RenderAngle="-1.5708">
<Button Width="90" Height="36" Content="Sales" />
<Button Width="90" Height="36" Content="Finance" />
<Button Width="90" Height="36" Content="HR" />
<Button Width="90" Height="36" Content="IT" />
<Button Width="90" Height="36" Content="Legal" />
<Button Width="90" Height="36" Content="Marketing" />
<Button Width="90" Height="36" Content="Operations" />
<Button Width="90" Height="36" Content="Support" />
</panels:CircularPanel>
</Window>A bound list laid out round a ring that turns slowly and continuously.
<ItemsControl ItemsSource="{Binding Products}" Width="400" Height="400">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<panels:CircularPanel ItemsClosenessFactor="3">
<panels:CircularPanel.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="RenderAngle"
From="0" To="6.2832" Duration="0:0:30"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</panels:CircularPanel.Triggers>
</panels:CircularPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Thumbnail}" Width="64" Height="64" ToolTip="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>API reference
Binarymission.WPF.Controls.Panels
class CircularPanel | A layout panel that places its children round a circle or an ellipse - evenly round the whole ring, or fanned across part of it - and can turn the ring to any angle. |
enum GapAngleCalculationStrategy | The ways CircularPanel can work out the angle between one child and the next. |