Welcome to MSDN Blogs Sign in | Join | Help

LB-SV-WHY [Three wacky uses for Silverlight 2's ListBox and ScrollViewer!]

In my Silverlight 2 ListBox/ScrollViewer FAQ I described some common scenarios and demonstrated how to implement them with sample XAML/code. In this post I demonstrate three UNcommon ListBox/ScrollViewer scenarios - again showing the XAML/code that makes them possible.

Because sometimes the power of a thing only becomes clear when it's being abused. :)

 

ListBox: Planets

When I saw Beatriz Costa's "PlanetsListBox" WPF demo of a fully functioning ListBox that looked like the solar system, I was stunned and knew I had to port it to Silverlight.

Planets shown smaller than actual size

So I downloaded the WPF project, created a new Silverlight application, copied over the implementations of the classes SolarSystem, SolarSystemObject, and ConvertOrbit, and went to work migrating the XAML. With one small exception, the code had no changes for Silverlight. As you'd expect, the XAML got a variety of minor tweaks because Silverlight is a subset of WPF and I was moving in the "wrong" direction. In particular, I made the following changes to the original implementation:

  • Switched to inline styles because Silverlight does not support implicit styles
  • Switched from a Trigger-based selection indicator (the yellow circle) to one based on the Silverlight parts model
  • Manually created Canvas bindings in PrepareContainerForItemOverride because Silverlight wasn't creating the attached property bindings in XAML
  • Manually created ToolTip contents/bindings in a custom IValueConverter because bindings in the ToolTip XAML were unexpectedly seeing a null DataContext
  • Changed the type of SolarSystemObject.Image from Uri to string and changed the image resource paths so that binding to Silverlight's Image.Source worked
  • Switched to Canvas.Top because Silverlight does not support Canvas.Bottom
  • Converted all images to JPEG format because GIF is not supported by Silverlight

 

ListBox: Slideshow

One day I was working on a perfectly sensible ListBox sample with images when my teammate Ted suggested making a simple Slideshow with ListBox. It's not the craziest idea he's ever had, so I decided to humor him.

It's not much of a list anymore...

The basic idea is simple: Populate the ListBox with images and then size it so only one of them shows at a time. You can use the dedicated Previous/Next Buttons to change slides - or click on the ListBox and press the usual keys (arrow Up/Down, Home/End, Page Up/Down). Because the Button states are updated in the SelectionChanged handler, they're kept in sync. Here's the complete implementation:

<UserControl x:Class="ListBoxSlideShow.Page"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls">
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">

        <!-- Column/row definitions -->
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <!-- ListBox slide display -->
        <ListBox
            x:Name="Display" Grid.ColumnSpan="2" Width="484" Height="364"
            controls:ScrollViewer.HorizontalScrollBarVisibility="Hidden"
            controls:ScrollViewer.VerticalScrollBarVisibility="Hidden">

            <!-- Style to size all images to desired size -->
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="Width" Value="480"/>
                    <Setter Property="Height" Value="360"/>
                </Style>
            </ListBox.ItemContainerStyle>

            <!-- Slide images -->
            <!-- Note: Sample images are from C:\Windows\Web\Wallpaper\*
                       Update that path if necessary for your machine -->
            <Image Source="img10.jpg"/>
            <Image Source="img7.jpg"/>
            <Image Source="img8.jpg"/>
            <Image Source="img9.jpg"/>
        </ListBox>

        <!-- Previous/Next buttons -->
        <Button x:Name="Previous" Grid.Column="0" Grid.Row="1" Content="Previous"/>
        <Button x:Name="Next" Grid.Column="1" Grid.Row="1" Content="Next"/>
    </Grid>
</UserControl>
using System;
using System.Windows.Controls;

namespace ListBoxSlideShow
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();

            // Hook button event handlers to change slides
            Previous.Click += delegate { ChangeSlide(Display.SelectedIndex - 1); };
            Next.Click += delegate { ChangeSlide(Display.SelectedIndex + 1); };

            // Update button states if necessary
            Display.SelectionChanged += delegate
            {
                Previous.IsEnabled = (0 < Display.SelectedIndex);
                Next.IsEnabled = (Display.SelectedIndex < Display.Items.Count - 1);
            };

            // Change to first slide
            ChangeSlide(0);
        }

        private void ChangeSlide(int index)
        {
            // Select specified slide and bring it into view
            Display.SelectedIndex = Math.Max(0, Math.Min(Display.Items.Count - 1, index));
            Display.ScrollIntoView(Display.SelectedItem);
        }
    }
}

 

ScrollViewer: Marquee

On a discussion list one day, someone innocently asked for a way to scroll text. I immediately thought: <MARQUEE>!

Welcome back to Web 1.0!

Again, the idea is simple: Put arbitrary content inside a ScrollViewer, hide its ScrollBars, and adjust its HorizontalOffset on a timer. I chose to have the content bounce at each end, but you could just as easily snap it back to the beginning. Here's the complete implementation:

<UserControl x:Class="ScrollViewerMarquee.Page"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>

        <!-- Marquee-like ScrollViewer -->
        <ScrollViewer x:Name="Marquee" Width="200"
                      VerticalAlignment="Center"
                      HorizontalScrollBarVisibility="Hidden"
                      VerticalScrollBarVisibility="Disabled">

            <!-- Arbitrary nested content -->
            <TextBlock Text=" This message bounces! "
                       FontFamily="Arial Black" FontSize="40"/>
        </ScrollViewer>
    </Grid>
</UserControl>
using System;
using System.Windows.Controls;
using System.Windows.Threading;

namespace ScrollViewerMarquee
{
    public partial class Page : UserControl
    {
        // Timer and direction variables
        private DispatcherTimer _timer;
        private int _delta = 1;

        public Page()
        {
            InitializeComponent();

            // Create timer to tick every 10ms
            _timer = new DispatcherTimer
            {
                Interval = TimeSpan.FromMilliseconds(10)
            };

            // Attach a Tick handler to do the scrolling
            _timer.Tick += delegate
            {
                // Adjust the horizontal offset
                Marquee.ScrollToHorizontalOffset(Marquee.HorizontalOffset + _delta);

                // Flip direction if necessary
                if ((0 < Marquee.ViewportWidth) &&  // (NOOP if not visible yet)
                    ((Marquee.ScrollableWidth <= Marquee.HorizontalOffset) ||
                     (Marquee.HorizontalOffset <= 0)))
                {
                    _delta = -_delta;
                }
            };

            // Start the timer
            _timer.Start();
        }
    }
}

 

I've made the complete source code I used to build these samples available as an attachment to this post for anyone to play around with. If you come up with your own wacky use for ListBox or ScrollViewer, please let me know. It's always interesting to see the clever, creative ways people end up using stuff like this!

Published Wednesday, March 12, 2008 1:58 PM by Delay
Filed under:

Attachment(s): LB-SV-WHY.zip

Comments

# Silverlight Cream for March 13, 2008 -- #220

Thursday, March 13, 2008 9:55 AM by Community Blogs

Thursday the 13th Cream :) Delay on SL2 controls, Andy Beaulieu on Collision Detection, Zhiming Xue gives

# Silverlight Tips, Tricks, Tutorials and Links Page

Wednesday, April 02, 2008 5:03 AM by ScottGu's Blog

I'll be using this page to link to Silverlight 2 articles and posts (both ones I write as well ones by

# Silverlight技巧,诀窍,教程和链接

Wednesday, April 09, 2008 1:02 AM by 大宋提刑官

Silverlight技巧,诀窍,教程和链接

【原文地址】SilverlightTips,Tricks,TutorialsandLinksPage

我将使用本页链接到有关Silve...

# Silverlight 2 ListBox Abuse

Tuesday, May 13, 2008 3:50 PM by POKE 53280,0: Pete Brown's Blog

During all my Silverlight and WPF talks, one point I try to make is that in those technologies, the important

# Silverlight 2 ListBox Abuse

Tuesday, May 13, 2008 4:23 PM by Community Blogs

During all my Silverlight and WPF talks, one point I try to make is that in those technologies, the important

# Spinning out of control!

Tuesday, May 13, 2008 7:56 PM by foo, bar and donkey

What's going on? Well...I was wondering what control to explore this week. Currently I have my Sherlock

# re: LB-SV-WHY [Three wacky uses for Silverlight 2's ListBox and ScrollViewer!]

Sunday, June 01, 2008 2:06 AM by markheath

Great post.

I like the idea for the scrolling text. I tried to do this with Silverlight alpha 1.1 by animating a textblock to move across a canvas with a clip rectangle. I never got it working quite right though because I couldn't find out a way of working out how long the TextBlock would be (its width just returned zero).

# Silverlight 2 ListBox Abuse

Sunday, June 29, 2008 12:01 AM by DEVELOPMENT SITE - NOT MY PUBLIC BLOG

During all my Silverlight and WPF talks, one point I try to make is that in those technologies, the important aspect of an out-of-the-box control is not its particular display properties, but its model and its ability to be customized. Back when we used

# Columns of a different color [Customizing the appearance of Silverlight charts with re-templating and MVVM]

Wednesday, February 04, 2009 3:29 AM by Delay's Blog

When we created Silverlight Charting (background reading here and here ), we tried to make things as

Anonymous comments are disabled
 
Page view tracker