Last week I found myself needing a Silverlight layout control that arranges its items radially so I could use it to template a ListBox. A quick Web search revealed a number of RadialPanel implementations, but none that offered the features I needed. For example, I wanted to be able to rotate the items in the panel to create a spoked arrangement. But I also wanted to have the option of NOT rotating the items to achieve a more traditional layout.
So I built a RadialPanel that supports both options. It has three key properties (all dependency properties) that you can use to configure it:
To demonstrate, I declared a ListBox containing eight colored rectangles and assigned a RadialPanel to the ListBox's ItemsPanel property:
<ListBox Width="600" Height="600">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<custom:RadialPanel Radius="200" ItemAlignment="Center"
ItemOrientation="Upright" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<Rectangle Width="75" Height="75" Fill="Red" />
<Rectangle Width="75" Height="75" Fill="Orange" />
<Rectangle Width="75" Height="75" Fill="Yellow" />
<Rectangle Width="75" Height="75" Fill="Green" />
<Rectangle Width="75" Height="75" Fill="Blue" />
<Rectangle Width="75" Height="75" Fill="Darkblue" />
<Rectangle Width="75" Height="75" Fill="Purple" />
<Rectangle Width="75" Height="75" Fill="#ff80c0" />
</ListBox>
Next, I created another RadialPanel ListBox, but this time I set ItemOrientation to "Rotated" and used TextBlocks as ListBox items. I also set ItemAlignment to "Left" to align the TextBlocks along the inside radius:
<ListBox Width="600" Height="600" FontSize="20">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<custom:RadialPanel Radius="150" ItemAlignment="Left"
ItemOrientation="Rotated" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<TextBlock Text="Jeff Prosise" Foreground="Red" />
<TextBlock Text="Jeffrey Richter" Foreground="Orange" />
<TextBlock Text="John Robbins" Foreground="Green" />
<TextBlock Text="Steve Porter" Foreground="Blue" />
<TextBlock Text="Keith Rome" Foreground="Blue" />
<TextBlock Text="Rik Robinson" Foreground="Darkblue" />
<TextBlock Text="Andy Hopper" Foreground="Purple" />
<TextBlock Text="Sergio Lascio" Foreground="#ff80c0" />
...
</ListBox>
And here was the result:
I posted the source code in case you need a RadialPanel, too. It works in Silverlight 2 and in Silverlight 3 Beta 1. Feel free to use my RadialPanel in projects of your own, with one condition: let me know if you find bugs. I think I accounted for everything, but custom layout controls are tricky to write, and many of the custom layout controls that are bandied about the Web aren't very robust.
Incidentally, if you're coming to TechEd next week and want to see lots of cool Silverlight samples, drop by my Silverlight precon on Sunday. The last couple of hours of the day will be devoted to Silverlight 3, so it's sure to be a blast!
On May 4 2009 3:50 AMBy jprosise
Cool... I was working on something similar - yes, with the option for rotating or not. Might pick this up and add animation :-)
I was considering animation, too, or even better, the ability to spin the items using a gesture, complete with physics. Wouldn't that be cool? :-)
Silverlight Contest app updated with new RadialPanel
Isn’t RSS great!? Today I saw something wonderful pop in the feed from Jeff Prosise . One of the problems
This is pretty cool! Is there a way to make it spin a certain angle? Meaning... I would like to have a pointer graphic pointing to a particular ListBoxItem ( Like the "Price is Right" Wheel ) and have two Buttons to control the spin direction ( Clockwise/Counter-Clockwise ) based on Button clicked.
Also, the physics and gesture behaviors are neat. Are you going to implement this? If so, do you have to wait until Blend 3 is released or could you add now?
Could this be added to the Silverlight Toolkit?
Keep up the good work.
Adding a property to control the angle would be easy; I'll add it to the list of suggestions.
Yes, I'll probably add the gesture support so you can spin the whole thing like a wheel. It doesn't have to wait for Blend 3; it can be done right now.
First, though, I have a couple of other ideas that I want to code up. One is a really cool custom pixel shader that I can't wait to get out in the public. I think people will find it useful because it's not a one-trick pony like most pixel shaders. But I'd better stop right there for now. :-)
Neat! I have worked out a similar panel, minus rotation, but with one additional property: a "percentage" of available space to fit items in. For example, a value of 180 would only fit items on half of the panel, with the other half left blank.
As for the rotation - adding an Offset property and a behaviour to animate that would probably work.
Let's say I databind a list of employees that are in different groups to the radial control and each group will be represented by a color. How could you set the color for each employee depending on group? (e.g. IT = Green, HR = Red, Engineering = Blue, etc. ).
Also, have you tried this with WPF? Thanks
Isn’t RSS great!? Today I saw something wonderful pop in the feed from Jeff Prosise . One of the problems
Very nice Jeff,
This is some very nice work from you.
-
Mark Monster
Very nice work!
a question: what do you achieve by making the class 'public' and the constructor 'static' ?
The constructor needs to be static so you can initialize the static fields representing the dependency properties.
first time i see someone do it this way.
i initialize them on the class level, like so:
public static readonly DependencyProperty MyProperty = DependencyProperty.Register(...)
(this is also how MS do it)
Nice Control.
I've tried this in WPF but...
VisualTree of ItemsPanelTemplate must be a single element.
links for 2009-05-19
Dear Sir,
I hope you are doing well. I got this email address from one of your contribution web site. I have launched a web site www.codegain.com and it is basically aimed C#,JAVA,VB.NET,ASP.NET,AJAX,Sql Server,Oracle,WPF,WCF and etc resources, programming help, articles, code snippet, video demonstrations and problems solving support. I would like to invite you as an author and a supporter.
Looking forward to hearing from you and hope you will join with us soon.
Thank you
RRaveen
Founder CodeGain.com
# re: Radial Layout in Silverlight
Friday, May 08, 2009 2:46 AM by Gtm
Nice Control.
I've tried this in WPF but...
VisualTree of ItemsPanelTemplate must be a single element.
Me.. too...
Can you please explain why?
I found the RadialPanel.cs's PropertyChangedCallback functions call
panel.Refresh(new Size(panel.Width, panel.Height));
If commenting out this line in the three call backs, the program works fine (but then you can't change the properties to make some effect at run time).
I'm trying to add the spinning feature to this sample. The control will need an angle offset parameter that can be set in code. I'm new to XAML/Silverlight though and don't know how to set properties of a custom control in code.
In essense, given the ListBox object in in Page.xaml.cs, how do I do something like
myRadialPanel.AngleOffset = 15?
I would like to modify the radius using code behind in c# by the main.xaml.cs program. How would I do it?
I figured out how to get the radius.
private void RadialPanel1_Loaded(object sender, RoutedEventArgs e)
{
radialpanelxaml =(RadialPanel) sender;
int radialpanelradius = 200;
radialpanelxaml.Radius = radialpanelradius;
}
I used the Radial Panel to create a nice Prize wheel animation. You can see the article in code project
Title: Silverlight Prize Wheel Animation using Custom Circular ListBox Control
Link: http://www.codeproject.com/KB/silverlight/PrizeWheel.aspx
and live at
http://www.svstechnology.com/PrizeWheel_Demo.aspx
I want to thank Jeff Prosise for inspiring me.
Vijay
Really a nice piece of code, i was looking for it since hours.