I spent quite awhile over the past few days scouring the web looking for a way to do something in Silverlight that should be a no-brainer. Why is it that when new languages come along, they make you completely relearn everything you’ve known for years and years in order to accomplish the same thing? I digress.
I wanted to simply pop up a window on top of my current window. In the good ol’ days of Visual Basic and C#, it was simply Form.Show() and you’d have your new window pop up with all the controls and content on them. How easy was that?
Ah, but then along comes Silverlight. Mind you, I think Silverlight has some good potential, and some of the demos I’ve seen are pretty neat. However, the simplest tasks seem to take a long time to learn how to do. Try searching for popping up an alert box and you’ll get many references to popping up a Javascript alert box from within Silverlight. Good grief! If I wanted a Javascript alert box with just the OK and Cancel buttons, I would just stick with HTML and move on. I rant . . .
It dawned on me this afternoon that I wasn’t speaking the Silverlight lingo. You see, as I see it now (and I could still be totally wrong), Silverlight is a graphical platform upon which you can draw your content programmatically. A “window” is not a window. It’s a Canvas. Once that lightbulb turned on, it was a little easier to figure out (because I still haven’t found a decent example) how to open up another Canvas. So, I’ll put my code down here for you to see. It’s a real live example of how to open up one Canvas over top of another.
First, we have the XAML file:
<UserControl x:Class="SLFirst.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Canvas x:Name="CanvasRoot" Background="Bisque">
<Button x:Name="btnOpen" Content="Open" Width="60" Height="20" Canvas.Top="10" Canvas.Left="10" Click="btnOpen_Click" />
<!-- define second canvas here -->
<Canvas x:Name="Canvas2" Background="Beige" Width="300" Height="200" Canvas.Top="50" Canvas.Left="50" SizeChanged="Canvas2_SizeChanged">
<TextBlock Text="Canvas #2" Canvas.Top="95" Canvas.Left="20" />
<Button x:Name="btnClose" Content="Close" Width="60" Height="20" Canvas.Top="170" Canvas.Left="230" Click="btnClose_Click" />
</Canvas>
</Canvas>
</UserControl>
One MAJOR thing to note is the fact that we currently have to have a SizeChanged event on Canvas2. The reason for this is due to a bug (confirmed by Microsoft) in the current beta that doesn’t display all the objects within the Canvas until you mouseover them. The trick we’re using is to leave Canvas2 visible until the SizeChanged event fires, then make Canvas2 hidden by setting the visibility property to Collapsed. This trick does not work with the Loaded event. For more info on this issue, see http://silverlight.net/forums/t/10906.aspx.
Next, comes the XAML’s .cs file. You’ll note in the XAML file, we have btnOpen, btnClose and Canvas2_SizeChanged events. These will probably be auto-created for you with Visual Studio 2008. If not, you’ll have to created them yourself. Either way, you’ll need to add the code in each event. Here’s the code:
private void btnOpen_Click(object sender, RoutedEventArgs e)
{
Canvas2.Visibility = Visibility.Visible;
}
private void btnClose_Click(object sender, RoutedEventArgs e)
{
Canvas2.Visibility = Visibility.Collapsed;
}
private void Canvas2_SizeChanged(object sender, SizeChangedEventArgs e)
{
Canvas2.Visibility = Visibility.Collapsed;
}
Here’s how it works. The CanvasRoot and Canvas2 canvases load up. The Canvas2 SizeChanged event fires and that runs Canvas2_SizeChanged in the code-behind. This simply makes Canvas2 hidden. When you click on the Open button, that fires btnOpen, which simply makes Canvas2 visible in the btnOpen_Click method. Then, to make Canvas2 disappear again, just click Close, which runs the btnClose_Click event. That method simply makes Canvas2 hidden.
That’s it. I’ll have to play around with this some more, but I can see a lot of good use to this method. Of course, since I know very little about Silverlight, I’m guessing I’m missing something here, but it works for now.
