Playing around with Silverlight 3… a late Easter Egg hunt – Revealed!
About a week and a half ago I issued a challenge to folks to figure out what the Silverlight 3 application below does. I dropped a few hints, but nobody guessed it! I had hoped for a few more guesses, but c’est la vie, I suppose. In the meantime, I should fulfill my end of the bargain and reveal the secrets of my mystery application, and some of the things I learned while putting it together.
To view the app, you’ll need the Silverlight 3 Beta installed on your machine (download links here):
Windows:
http://go.microsoft.com/fwlink/?LinkID=143433
Mac:
http://go.microsoft.com/fwlink/?LinkID=143434
First, let me show you the “visible” portion of my application. Pardon my slow reveal, but it will help create drama, I promise!
<Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid DataContext="{Binding Source={StaticResource SampleDataSource}}"> <dataControls:DataForm CurrentIndex="{Binding ElementName=dg, Mode=TwoWay, Path=SelectedIndex}" HorizontalAlignment="Right" Margin="0,8,8,223" Width="267" ItemsSource="{Binding Mode=OneWay, Path=Collection}"/> <chartingToolkit:Chart Height="211" HorizontalAlignment="Right" Margin="0,0,8,8" DataContext="{Binding Mode=OneWay, Path=Collection}" VerticalAlignment="Bottom" Width="267" Title="Chart Title"> <chartingToolkit:ScatterSeries SelectedItem="{Binding ElementName=dg, Mode=TwoWay, Path=SelectedItem}" DependentValuePath="Y" IndependentValuePath="X" ItemsSource="{Binding Mode=OneWay}" AnimationSequence="FirstToLast" IsSelectionEnabled="True"/> </chartingToolkit:Chart> <data:DataGrid x:Name="dg" Margin="8,8,279,223" ItemsSource="{Binding Mode=OneWay, Path=Collection}" AutoGenerateColumns="False"> <data:DataGrid.Columns> <data:DataGridTextColumn Header="Bar" Binding="{Binding Path=Bar}"/> <data:DataGridTextColumn Header="Bat" Binding="{Binding Path=Bat}"/> <data:DataGridTextColumn Header="Baz" Binding="{Binding Path=Baz}"/> <data:DataGridTextColumn Header="Foo" Binding="{Binding Path=Foo}"/> <data:DataGridTextColumn Header="Title" Binding="{Binding Path=Title}"/> <data:DataGridTextColumn Header="X" Binding="{Binding Path=X}"/> <data:DataGridTextColumn Header="Y" Binding="{Binding Path=Y}"/> </data:DataGrid.Columns> </data:DataGrid> <controls:Calendar Height="211" Margin="8,0,279,8" VerticalAlignment="Bottom"/> </Grid> <Button Grid.Row="1" Content="Reset" Click="Button_Click" Margin="8,0,8,0" Height="30" /> </Grid>
So there you go. The XAML is fairly simple – it uses some of the Silverlight SDK controls (DataForm, DataGrid, and Calendar) as well as the Toolkit’s Chart control. A few folks in the comments of the original post remarked on the behavior of the controls here. Some fun things to notice: the Chart, DataGrid, and DataForm are all bound to the same collection. Furthermore, their SelectedItems are all bound together as well. The result is that changing a value in the DataGrid or DataForm will move it in the chart and update its value in the other controls. All cool stuff, even though I put it in the app to throw you off!
You’ll notice that I used ElementName binding – new in SL3 (imported from WPF XAML) to accomplish all of this behavior. With ElementName binding and many of the other new Silverlight features, you can really make rich, dynamic applications with very little code. And with the new features in the Blend 3 preview, building this app was easier than ever. The new Sample Data feature in Blend 3 is great for prototyping:
With the Sample Data feature, you can define a data source (as I did above) and add fields that are simple (strings, ints, etc.), complex (objects on which you can add other fields"), or collections. Blend will generate sample data ranging from lorem ipsum text to random numbers. You can then bind your UI to this sample data and use the binding UI in Blend to set up your bindings:
Again, very cool stuff. Blend 3 and Silverlight 3 make it really easy to construct rich UI for your application and do it quickly. All in all, building this piece of the mystery application using Blend 3 took me no more than an hour, and the only reason it took that long is that I spent some time playing with some of the Blend features and the Chart control!
Ok, ok, I’m stalling, I know…
I guess it’s time for me to reveal what the real Easter Egg is. “All of that Silverlight 3 and Blend 3 stuff is great…”, I’m sure you’re saying, “but get to the secret already!”
First, let me outline the hints I gave:
- I pointed you to gizmodo.com – an article that appeared the day of the post. That morning, a fun little article about an Easter Egg on a popular social networking site appeared.
- In the comments, I pointed out that the business-like functionality was too serious of a guess!
- The Reset button actually does something.
In truth, really only the first hint would give you and idea of what to do with this application. Without taking a look there, you weren’t likely to figure out what to do with my application.
So, if you haven’t already figured it out from my revelations above, the easter egg in my application is that the Konami Code makes a super-secret special message appear! I figured if it’s good enough for Facebook, it’s good enough for me! Here’s what you need to do:
Click the application to give it focus. Hit the following keys:
Up, Up, Down, Down, Left, Right, Left, Right, B, A
And observe!
And true to form, the Reset button will hid the message and allow you to re-enter the code.
Enabling this functionality turns out to be pretty simple. For the purposes of this mystery application, I created a KonamiCode control that simply changes its visual state once the code is entered. Its template uses the new easing functions (very easy to set up in a visual state transition in Blend 3) in Silverlight to animate the rotation of the “secret message.” The KonamiCode control is a ContentControl, and listens for key presses on its content. For kicks, I made the control work more generally, allowing a developer to specify the keystrokes that will trigger the visual state change. Who knows, maybe someone will find something more useful to do with it!
With the KonamiCode control, you too can add the Konami Code Easter Egg to your Silverlight 3 applications! It’s as simple as wrapping your UI in the control, like so:
<KonamiCode:KonamiCodeControl x:Name="kcc"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid DataContext="{Binding Source={StaticResource SampleDataSource}}"> <dataControls:DataForm CurrentIndex="{Binding ElementName=dg, Mode=TwoWay, Path=SelectedIndex}" HorizontalAlignment="Right" Margin="0,8,8,223" Width="267" ItemsSource="{Binding Mode=OneWay, Path=Collection}"/> <chartingToolkit:Chart Height="211" HorizontalAlignment="Right" Margin="0,0,8,8" DataContext="{Binding Mode=OneWay, Path=Collection}" VerticalAlignment="Bottom" Width="267" Title="Chart Title"> <chartingToolkit:ScatterSeries SelectedItem="{Binding ElementName=dg, Mode=TwoWay, Path=SelectedItem}" DependentValuePath="Y" IndependentValuePath="X" ItemsSource="{Binding Mode=OneWay}" AnimationSequence="FirstToLast" IsSelectionEnabled="True"/> </chartingToolkit:Chart> <data:DataGrid x:Name="dg" Margin="8,8,279,223" ItemsSource="{Binding Mode=OneWay, Path=Collection}" AutoGenerateColumns="False"> <data:DataGrid.Columns> <data:DataGridTextColumn Header="Bar" Binding="{Binding Path=Bar}"/> <data:DataGridTextColumn Header="Bat" Binding="{Binding Path=Bat}"/> <data:DataGridTextColumn Header="Baz" Binding="{Binding Path=Baz}"/> <data:DataGridTextColumn Header="Foo" Binding="{Binding Path=Foo}"/> <data:DataGridTextColumn Header="Title" Binding="{Binding Path=Title}"/> <data:DataGridTextColumn Header="X" Binding="{Binding Path=X}"/> <data:DataGridTextColumn Header="Y" Binding="{Binding Path=Y}"/> </data:DataGrid.Columns> </data:DataGrid> <controls:Calendar Height="211" Margin="8,0,279,8" VerticalAlignment="Bottom"/> </Grid> <Button Grid.Row="1" Content="Reset" Click="Button_Click" Margin="8,0,8,0" Height="30" /> </Grid> </KonamiCode:KonamiCodeControl>
Anyhoo, here’s the code. You can download either just the control or the full source for the Mystery Application:
Enjoy! And let me know what you think! Even RIA apps deserve to have a little fun, and I hope this brings countless hours minutes of entertainment to folks reading my blog! :)
UPDATE: 5/19/2009 – 12:52 AM. Ok, just after I posted this, the following appeared on my WordPress admin dashboard. So perfect:
Furthermore, this plugin directed me to this site: http://konamicodesites.com/
I’ll have to get listed!
P.S. My colleague, coworker, and fellow PM Scott Morrison just returned from TechEd 2009 and posted some of the great Silverlight 3 and .NET RIA Services content that he demoed there. Check it out!
Update: 7/11/2009 9:48 PM – Samples updated for Silverlight 3!