CHAPTER 14 SILVERLIGHT INTRODUCTION 333 Hi Yo, Silver! Let’s create a Hello World (or Hi yo Silver) application: 1. Open the file ~\MainPage.xaml. 2. By default, MainPage.xaml will contain a Grid tag like the following: <Grid x:Name="LayoutRoot" Background="White"> </Grid> Silverlight and WPF allow you to nest tags inside one another. Enter the following between the Grid tags: <TextBlock>Hi yo Silver</TextBlock> You should now have something like the following: <UserControl x:Class="Chapter14.HelloSilverlight.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <TextBlock>Hi yo Silver</TextBlock> </Grid> </UserControl> 3. Press F5 to run your application. You should see the text Hi yo Silver displayed on a page. Understanding the Basics Let’s run through the lines of code to understand what they do. The following line tells the compiler which class to inherit from. (It is similar to ASP.NET’s inherits property in an .aspx or .ascx file.) x:Class="Chapter14.HelloSilverlight.MainPage" The lines beginning with xmlns import a number of WPF- and Silverlight-related namespaces (such as a using or imports statement). The following line creates a TextBlock on the page and sets the text to Hi yo Silver: <TextBlock>Hi yo Silver</TextBlock> NOTE Hi yo, Silver was a line said by the Lone Ranger as he rode away on his horse. It was on a TV/radio series that I am too young to remember, but it was the only Silver-related reference I could think of. Note the line xmlns:xx is a prefix you can use to refer to this namespace. You then use this prefix in the line x:name, which is similar in function to ASP.NET’s ID property. CHAPTER 14 SILVERLIGHT INTRODUCTION 334 Adding Content Content can be added either declaratively or programmatically. If you wanted to create the previous example programmatically, you could do so in MainPage.xaml.cs in the constructor as follows: TextBlock TextBlock = new TextBlock(); TextBlock.Text = "Hi yo Silver"; LayoutRoot.Children.Add(TextBlock); Note that the TextBlock control is added as a child element to the LayoutRoot control. Elements in a XAML page are maintained in a hierarchy like HTML’s document object model (DOM). The Children property is similar to ASP.NET’s Controls property. This hierarchy allows you to do some strange things such as nesting text boxes inside buttons that wouldn’t be possible with Windows forms. I can’t wait to see some of the appalling uses this feature will no doubt be used for. Let’s create an example to demonstrate this now: <Button Width="200" Height="100"> <TextBox Width="150" Height="20"></TextBox> </Button> Figure 14-5. Text box inside a button Adding Silverlight to your Application So back to the Hi yo Silver application. How did this end up being rendered in the browser? In Silverlight 3.0, applications are displayed using the object tag. Previous versions of Silverlight utilized an ASP.NET Silverlight tag that has since been depreciated (although still available on Codeplex). Object Tag Select the Chapter14.HelloSilverlight.Web project and open the file ~/Chapter14. HelloSilverlightTestPage.html. The page will contain an object tag similar to the following: <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> <param name="source" value="ClientBin/Chapter14.HelloSilverlight.xap"/> <param name="onError" value="onSilverlightError" /> <param name="background" value="white" /> <param name="minRuntimeVersion" value="3.0.40818.0" /> <param name="autoUpgrade" value="true" /> CHAPTER 14 SILVERLIGHT INTRODUCTION 335 <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40818.0" style="text-decoration:none"> <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/> </a> </object> Note the following from the preceding code: • An object tag is used to embed the Silverlight plug-in in the web page. • The object tag has a param value that references the JavaScript function onSilverlightError() to return any errors from Silverlight to the user via JavaScript. When you compile your Silverlight application, all the XAML, resources, references, and so forth get compressed into an XAML Application Package (XAP) file. The object tag has a property called Source that contains the location of the XAP file. Also note that the test page contains the following line: <script type="text/javascript" src="Silverlight.js"></script> Silverlight.js contains lots of functionality such as error handling, loading, and displaying the plug-in; routing messages to JavaScript; and upgrading the plug-in. If you want to customize how the Silverlight application is displayed, you can modify the parameters passed into Silverlight.js (or even Silverlight.js itself). Pages in Silverlight Silverlight allows you to divide your application up into a number of XAML pages. However, you cannot just move between pages as you do in ASP.NET with functions such as Response.Redirect or Server.Transfer. A popular way of implementing navigation between pages is to create one page with a container control that you then load other XAML files into. TIP Silverlight 3.0 introduced an easier way (NavigationApplication) that you will examine in Chapter 15. You will create this paging functionality now because it will make it easy to navigate through the examples: 1. Right-click Chapter14.HelloSilverlight solution. 2. Select Add Class. 3. Call the class PageNavigator. 4. Enter the following code: using System; using System.Net; using System.Windows; using System.Windows.Controls; CHAPTER 14 SILVERLIGHT INTRODUCTION 336 using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace Chapter14.HelloSilverlight { public class PageNavigator { private static Grid RootLayoutElement; static PageNavigator() { RootLayoutElement = Application.Current.RootVisual as Grid; } public static void LoadPage(UserControl NewControl) { //Get reference to old control var OldUserControl = RootLayoutElement.Children[0] as UserControl; //Add new control RootLayoutElement.Children.Add(NewControl); //Remove old control RootLayoutElement.Children.Remove(OldUserControl); } } } Creating a Silverlight User Control You will now create a menu page with a number of buttons to take you to the examples you will create: 1. Right-click the Chapter14.HelloSilverlight solution and select Add➤New Item. 2. Select Silverlight User Control. 3. Enter the name MainMenu. 4. Note that at the top of the XAML code is a control declaration: <UserControl x:Class="Chapter14.HelloSilverlight.MainMenu" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> CHAPTER 14 SILVERLIGHT INTRODUCTION 337 You want the menu control to span the whole page, so remove this code: d:DesignHeight="300" d:DesignWidth="400 5. Enter the following XAML inside the LayoutRoot Grid to create buttons to navigate to the test pages: <TextBlock FontSize="40" Canvas.Left="200" Canvas.Top="25" >Silverlight Demo</TextBlock> <StackPanel Canvas.Left="300" Canvas.Top="150" Orientation="Vertical" VerticalAlignment="Top"> <Button x:Name="cmdStackPanel" Content="Stack Panel"></Button> <Button x:Name="cmdGrid" Content="Grid"></Button> <Button x:Name="cmdAnimation" Content="Animation"></Button> <Button x:Name="cmdCallJS" Content="Call JS"></Button> <Button x:Name="cmdMediaTest" Content="Media"></Button> <Button x:Name="cmdDataBind" Content="Data Binding"></Button> </StackPanel> Okay, nearly done. But when the Silverlight application is first loaded, you want to load MainMenu.xaml rather than MainPage.xaml. You can do this by editing a file called App.xaml. App.xaml App.xaml handles global events in a manner similar to Global.asax. Open ~/App.xaml.cs. By default, App.xaml.cs has code such as the following: private void Application_Startup(object sender, StartupEventArgs e) { this.RootVisual = new MainPage(); } This loads the MainPage.xaml file when the application starts. You want to alter this to load the MainMenu.xaml file instead. Change the Application_startup method to the following: private void Application_Startup(object sender, StartupEventArgs e) { Grid root = new Grid(); root.Children.Add(new MainMenu()); this.RootVisual = root; } Styles Silverlight allows you to define set styles for objects in a manner that is a cross between CSS and ASP.NET themes. You will create a simple style that will format the page title on the menu page. CHAPTER 14 SILVERLIGHT INTRODUCTION 338 6. Open up ~/App.xaml. 7. Inside the <Application.Resources> block, enter the following: <Style x:Key="MyStyle" TargetType="TextBlock"> <Setter Property="FontFamily" Value="Comic Sans MS"/> <Setter Property="FontSize" Value="54"/> <Setter Property="Foreground" Value="#FF0000FF"/> </Style> 8. Now go back to MainMenu.xaml and find the line where it says the following: <TextBlock FontSize="40" Canvas.Left="200" Canvas.Top="25">Silverlight Demo</TextBlock> 9. Add the following attribute to this tag to reference the style you created in App.xaml: Style="{StaticResource MyStyle}" Your tag should now look like this: <TextBlock FontSize="40" Canvas.Left="200" Canvas.Top="25" Style="{StaticResource MyStyle}">Silverlight Demo</TextBlock> APPLICATION.RESOURCES The Application.Resources section allows you to hold much more complex styles than you have just created. It can be used to hold pretty much any set of properties you might want to reuse. For example, you could include colors, gradients, or even control templates. Positioning Elements One of the most confusing parts of Silverlight and WPF is element positioning. When you start working with Silverlight and WPF, it is quite common to find yourself wondering why an element is not displaying. This is normally due to the following: • You haven’t set the width or height. • Your element is obscured by another element. • You have positioned the element off the screen. • Your element is transparent. Silverlight positions elements using two axes running from the top-left corner of the screen called Left (horizontal axis) and Top (vertical axis). The top-left corner is referred to as coordinates 0, 0 (see Figure 14-6). . xmlns:d="http://schemas.microsoft.com/expression/blend/ 200 8" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/ 200 6" mc:Ignorable="d" d:DesignHeight=" 300 " d:DesignWidth=" ; 40 0">. xmlns:d="http://schemas.microsoft.com/expression/blend/ 200 8" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/ 200 6" mc:Ignorable="d" d:DesignHeight=" 300 " d:DesignWidth=" ; 40 0">. <Button Width=" 200 " Height=" 100 "> <TextBox Width="1 50& quot; Height=" 20& quot;></TextBox> </Button> Figure 14- 5. Text box inside a button