Silverlight 2 Timeline Panel

A while back I
posted on creating a custom layout panel in WPF
that could arrange items based
on an assigned date property to create a timeline view. Working through the creation
of this panel taught me a great deal about how powerful the layout system was in WPF,
and now how that power and flexibility extends into Silverlight
2
.

The Silverlight
2 layout system
is largely based on the use of panels, which includes the Canvas,
Grid, and Stack Panel. Silverlight 2 includes a base Panel that you are able to derive
from and override it’s default layout behavior. In addition to the basic functionality
that comes with Panel, it provides two methods that you can easily override to create
your own behavior. MeasureOverride and ArrangeOverride are
the heart of the layout, determining the the position of elements. It’s essentially
a to phase process where MeasureOverride examines the child elements of the panel
to see what size they would “like to be”. The ArrangeOverride the tells the children
the size and location they “are going to be”, based on whatever calculations you specify.

This example shows how using a custom attached property to specify an event date for
any child element placed on the panel that ArrangeOverride can then use to position
them.

 

Silverlight TimeLinePanel - Windows History Timeline

This view showing the history of Windows version release dates is created using this
XAML markup:

 <local:TimelinePanel Width="800" Height="280" StartDate="1/1/1984" StopDate="12/12/2010" Background="LightGray"> <TextBlock local:TimelinePanel.EventDate="11/1/1985">Windows
1.0</TextBlock> <TextBlock local:TimelinePanel.EventDate="12/1/1987">Windows
2.0</TextBlock> <TextBlock local:TimelinePanel.EventDate="5/1/1990">Windows
3.0</TextBlock> <TextBlock local:TimelinePanel.EventDate="4/1/1992">Windows
3.1</TextBlock> <TextBlock local:TimelinePanel.EventDate="5/30/1995">Windows
NT 3.51</TextBlock> <TextBlock local:TimelinePanel.EventDate="8/24/1995" >Windows
95</TextBlock> <TextBlock local:TimelinePanel.EventDate="6/1/1996">Windows
NT 4</TextBlock> <TextBlock local:TimelinePanel.EventDate="6/1/1998">Windows
98</TextBlock> <TextBlock local:TimelinePanel.EventDate="2/1/2000">Windows
2000</TextBlock> <TextBlock local:TimelinePanel.EventDate="7/1/2000">Windows
Me</TextBlock> <TextBlock local:TimelinePanel.EventDate="10/1/2001">Windows
XP</TextBlock> <TextBlock local:TimelinePanel.EventDate="1/1/2007">Windows
Vista</TextBlock> </local:TimelinePanel>

 

As you can see from the XAML markup, a Start and Stop date are specified for the date
range that the panel will display. Each child element, in this case TextBlock’s have
an EventDate property specified. It should be noted that the TextBlock itself has
no concept of an event date coded into it. EventDate is an Attached Property, a dependency
property that can be “attached” to any element.

“An attached property is a concept defined by XAML. An attached property
is intended to be used as a type of global property that is settable on any object
element in XAML. In Silverlight version 2, attached properties are typically defined
as a specialized form of dependency property that does not have the conventional property
wrapper in the object’s CLR object model
.”

MSDN has more details on attached
properties in Silverlight 2
online.

In the ArrangeOverride code I simply scale the date based on the EventDate’s relative
position to the StartDate and StopDate of the TimeLinePanel giving me a horizontal
position. For the vertical position I track the position of the previous element and
if it overlaps I place it below, creating a cascading effect for overlapping elements.

protected override Size
ArrangeOverride(Size finalSize) { double lastX = 0; double lastY
= 0; foreach (UIElement element in this.Children)
{ DateTime eventDate = (DateTime)element.GetValue(EventDateProperty); double pos
= ScaleDate(eventDate); double left = finalSize.Width *
pos; double top = (double)element.GetValue(VerticalOffsetProperty); if (double.IsNaN(top)
== true) top = 0.00; double width
= element.DesiredSize.Width; double height = element.DesiredSize.Height; if (lastX
+ width > left) { top = lastY + 20 + (double)element.GetValue(VerticalOffsetProperty);
} else { top = 0 + (double)element.GetValue(VerticalOffsetProperty);
} element.Arrange(new Rect(left, top, width, height)); lastX
= left; lastY = top; } return finalSize; }

The use of custom panels for layout in Silverlight 2 creates a world of exciting possibilities,
giving developers and designers an incredibly flexible set of tools. With the ability
for panels to be reused within other controls such as the ListBox (Shown in my previous Solar
System ListBox Demo
) advanced user experiences become much easier to create. By
placing the TimeLinePanel into the ItemsPanelTemplate of ListBox and attaching the
EventDate to the ListBoxItem, I now have all of the functionality of a ListBox, with
the visual display of my TimeLinePanel.

<ListBox> <ListBox.ItemsPanel> <ItemsPanelTemplate> <local:TimelinePanel Width="800" Height="280" StartDate="1/1/1984" StopDate="12/12/2010" Background="LightGray"> </local:TimelinePanel> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBoxItem local:TimelinePanel.EventDate="11/1/1985"><TextBlock Text="Windows
1.0" /></ListBoxItem> <ListBoxItem local:TimelinePanel.EventDate="12/1/1987"><TextBlock Text="Windows
2.0" /></ListBoxItem> <ListBoxItem local:TimelinePanel.EventDate="5/1/1990"><TextBlock Text="Windows
3.0" /></ListBoxItem> <ListBoxItem local:TimelinePanel.EventDate="4/1/1992"><TextBlock Text="Windows
3.1" /></ListBoxItem> <ListBoxItem local:TimelinePanel.EventDate="5/30/1995"><TextBlock Text="Windows
NT 3.51" /></ListBoxItem> <ListBoxItem local:TimelinePanel.EventDate="8/24/1995"><TextBlock Text="Windows
95" /></ListBoxItem> <ListBoxItem local:TimelinePanel.EventDate="6/1/1996"><TextBlock Text="Windows
NT 4" /></ListBoxItem> <ListBoxItem local:TimelinePanel.EventDate="6/1/1998"><TextBlock Text="Windows
98" /></ListBoxItem> <ListBoxItem local:TimelinePanel.EventDate="2/1/2000"><TextBlock Text="Windows
2000" /></ListBoxItem> <ListBoxItem local:TimelinePanel.EventDate="7/1/2000"><TextBlock Text="Windows
Me" /></ListBoxItem> <ListBoxItem local:TimelinePanel.EventDate="10/1/2001"><TextBlock Text="Windows
XP" /></ListBoxItem> <ListBoxItem local:TimelinePanel.EventDate="1/1/2007"><TextBlock Text="Windows
Vista" /></ListBoxItem> </ListBox>

Silverlight TimeLinePanel replacing default ListBoxItemsPanel 

Live demo of TimeLinePanel

Silverlight
2 TimeLinePanel Demo Source Code

 

Technorati
Tags: , ,

Silverlight 2 Controls – Styles and Templates

With the release of Silverlight
2
, I’ve been working on updating a number of my existing demos as well as building
a number of new ones for upcoming presentations. One of my favorite features in Silverlight
2 (And WPF) is the ability to change the visuals of a control through styles and templates,
without impacting the control logic. The demo that really drove this home to me was
created by Beatriz Costa. Her post on The
power of Styles and Templates in WPF
showed a simple yet effective way to have
the visuals of controls can be altered, leaving the logic of the control intact to
do all of the expected ListBox stuff. (Fire events, provide a selected item, respond
to keyboard up/down). This flexibility and separation of control visuals from control
logic is one of the key elements of WPF, and now Silverlight.

I started with a some basic controls on a page including a databound ListBox and a
UserControl containing some TextBlocks.

image 

After applying the styles and templates the application visuals are transformed into
something much more interesting, while maintaining the complete functionality of a
ListBox, while appearing as a Solar System ListBox.

            <ListBox x:Name="listbox1" Height="600" Width="1000" SelectionChanged="listbox1_SelectionChanged" Template="{StaticResource
ListBoxTemp}" ItemContainerStyle="{StaticResource
DefaultListBoxItemStyle}" ItemTemplate="{StaticResource
ListBoxItemContainerPlanet}"> </ListBox>

image  

In order to take things a step further, I also replaced the ItemsPanel of the ListBox
with a custom carousel panel. The original CarouselPanel code I started with is by Jamie
Rodriguez
and found here.

                <ListBox.ItemsPanel> <ItemsPanelTemplate> <local:CarouselPanel x:Name="planets" Width="800" Height="600" Grid.Row="0" Speed="0.03" UseMousePosition="False" ScalePerspective=".2" /> </ItemsPanelTemplate> </ListBox.ItemsPanel>

The result is an interactive interface with the planets orbiting around the screen,
while still maintaining the full functionality of the underlying ListBox below.

image

Live Demo HERE

Source Code: (Soon)

Control Customization Documentation Resources:

Styling
and Templating Overview


Control
Styles and Templates


Creating
a Templatable Control

** And yes… I know the ongoing debate about Pluto being a “dwarf planet” and not a
“real” planet any more… deal with it.

Raleigh Code Camp 2008 &ndash; Fall Edition

Registration will soon be opening for the Raleigh Code Camp 2008 Fall Edition (RCC2008FE
for short). Keep an eye on www.codecamp.org and www.trinug.org to
register for the event in the near future. It’s going to be a crazy couple of weeks
for me here so I wanted to get this reminder out early.I was able to sneak a peak
at the session list and it’s action packed with a variety of great topics covering
pretty much every aspect of .Net development.

We’re also very excited to have Karl
Shifflett
back in the Carolinas as our keynote speaker. Karl who has recently
taken a position with Microsoft in Redmond will be covering some WPF and Silverlight related
topics including his recently released XAML Power Toys and Ocean.

If you have never attended a Code Camp event before, I strongly encourage you to plan
to attend. The events pack a variety of topics presented by a wide range of speakers,
both local and from afar. In addition to the presenters, the events attract an energetic
group of your peers interested in learning and expanding their .NET related skills.
This is a great way to cram much of the value of an industry conference into a local,
1 day, free to attend event. With some uncertainty  in the economy, this is a
great way to get some free training, network with your peers, and sharpen your skills.

With Code Camp falling just a couple of weeks after the Microsoft PDC conference,
I can pretty much guarantee that at least a few of the sessions will contain some
valuable details on things to come.

Silverlight 2 Released!

As you’ve likely heard, Microsoft has released Silverlight 2. I was fortunate to have
been involved along the way and getting to interact with many members of the various
teams involved. I want to start by offering a gigantic congratulations to everybody
involved. You guys did a great job moving things along with such speed an innovation!
Having had a chance to see a glimpse of what went on behind the scenes I have a tremendous
level of respect and admiration for that teams of great people that made this release
possible It is truly an amazing  and passionate group, and every member should
be proud. It seems like just yesterday that “Silverlight” was unveiled as the proper
name or WPF/E. I can’t wait to see the future innovation.

Some of the key highlights of this release include:

•.NET Framework support with a rich base class library.
This is a compatible subset of the full .NET Framework.

•Powerful built-in controls. These include DataGrid, ListBox,
Slider, ScrollViewer, Calendar controls and more.

•Advanced skinning and templating support. This makes it
easy to customize the look and feel of an application.

•Deep zoom. This enables unparalleled interactivity and
navigation of ultrahigh resolution imagery.

•Comprehensive networking support. Out-of-the-box support
allows calling REST, WS*/SOAP, POX, RSS and standard HTTP services, enabling users
to create applications that easily integrate with existing back-end systems.

•Expanded .NET Framework language support. Unlike other
runtimes, Silverlight 2 supports a variety of programming languages, including Visual
Basic, C#, JavaScript, IronPython and IronRuby, making it easier for developers already
familiar with one of these languages to repurpose their existing skill sets.

•Advanced content protection. This now includes Silverlight
DRM, powered by PlayReady, offering robust content protection for connected Silverlight
experiences.

•Improved server scalability and expanded advertiser support.
This includes new streaming and progressive download capabilities, superior search
engine optimization techniques, and next-generation in-stream advertising support.

•Cross-platform and cross-browser support. This includes
support for Mac, Windows and Linux in Firefox, Safari and Windows Internet Explorer.

For me personally, Silverlight 2 represents a great opportunity to leverage my existing
skill investment in .NET and extend beyond the server and desktop  into a richer
browser experience. I’ve been working on updating the code for a number of new posts
that I will be sharing in the days ahead, as well as updating some of my previous
samples.