Escolar Documentos
Profissional Documentos
Cultura Documentos
In this chapter you will learn about the very basic informations on Silverlight, its System Requirements and the pre-requisite to create a Silverlight application. After reading this chapter you will came to know about XAML, XAP file, Application XAML and how to host a Silverlight application.
What is Silverlight?
Silverlight is a powerful cross-browser & cross-platform technology for building the next generation web experience & rich internet applications for the web. You can run Silverlight in most of all the popular browsers like Internet Explorer, Firefox, Chrome, Safari etc. Silverlight can run in various devices and operating systems like Windows, Apple Mac OS-X and Windows Phone 7. Using Silverlight you can create rich, visually stunning web applications like flash. Also you can create smooth animations using Storyboards; you can stream media over the net etc. Silverlight web browser plug-in comes as free to install (approximately 4-5 MB in size). You can download the required plug-in from Microsoft Silverlight Site.
PC Type Windows PC
Processor RAM 500 MHz or higher, x86 or128 MB x64 bit processor Mac Power PowerPC G4 800 MHz or128 MB PC higher Mac Intel- Intel Core Duo 1.83 GHz or128 MB based higher
Operating System Windows XP SP2+ Mac 10.4.8 or higher Mac 10.4.8 or higher
Silverlight also supports Linux PCs. The plug-in name for Linux operating system is Moonlight and you can get the information about it in Mono Project's Moonlight site (http://www.monoproject.com/Moonlight).
MINIMUM SYSTEM REQUIREMENTS FOR INSTALLING SILVERLIGHT SDK FOR DEVELOPMENT IS AS FOLLOWS:
If you are a developer and want to start working on it, you must need the following environment to install the Silverlight tools.
Operating System Developer Tools Designers Tools Microsoft Windows XP Service Pack 2 or higher
Visual Studio 2008 SP1 (for Silverlight 3) Visual Studio 2010 (for Silverlight 3 & Silverlight 4) Microsoft Expression Blend 3 (for Silverlight 3) Microsoft Expression Blend 4 (for Silverlight 3 & Silverlight 4) Silverlight 3 Tools for Visual Studio 2008 SP1 Silverlight 4 Tools for Visual Studio 2010
Silverlight SDK
Before starting with the Silverlight application development be sure you have all the necessary softwares installed in your PC. If you dont have then follow the steps mentioned in Microsoft Silverlight Site (http://silverlight.net/getstarted/) to download & install the following items in your development environment:
Visual Studio 2008 SP1 for Silverlight 3 application development or Visual Studio 2010 for Silverlight 3 & Silverlight 4 application development Silverlight 3 Tools for Visual Studio 2008 SP1 or Silverlight 4 Tools for Visual Studio 2010 Expression Blend 3 for Silverlight 3 or Expression Blend 4 Preview for Silverlight 4 (optional) WCF RIA Services for Silverlight (optional) Silverlight 3 Toolkit or Silverlight 4 Toolkit based on your earlier version of Silverlight (optional)
Remember that, Silverlight 3 comes preinstalled with Visual Studio 2010 and hence if you are using Visual Studio 2010, you dont need to install the Silverlight 3 Tools for it. Using Visual Studio 2010 you can develop both Silverlight 3 and Silverlight 4 applications but Visual Studio 2008 SP1 only supports Silverlight 3. If you have proper development environment ready for Silverlight application you can proceed to the next chapter for creating our first simple Silverlight project. I am using Visual Studio 2010 RC and Silverlight 4 RC while writing these applications. Hence, the attached samples will not open in Visual Studio 2008.
What is XAML?
XAML stands for eXtended Application Markup Language. It is nothing but an XML file which is used to declaratively create the User Interface of the Silverlight or WPF applications. This XAML file generally rendered by the Silverlight plugin and displayed inside the browser window. When you compile your projects which includes XAML pages, those first converts into BAML (Binary Application Markup Language) and then rendered in the web browser window. Let use see a simple example of XAML here:
<TextBlock x:Name="txbTitle" Text="Hello Silverlight" FontFamily="Comic Sans MS" FontWeight="Bold"/>
The above XAML is a typical example where I am creating a text using the TextBlock control by specifying different properties as attributes to the control for name, font-family, weight, text etc.
x:Class="SilverlightApps.HelloSilverlight.App"> <Application.Resources> <!-- Brush --> <SolidColorBrush x:Name="solidBrushRed" Color="Red"/> <SolidColorBrush x:Name="solidBrushGreen" Color="Green"/> <SolidColorBrush x:Name="solidBrushBlue" Color="Blue"/> <!-- Styles --> <Style x:Key="styleButton" TargetType="Button"> <Setter Property="Background" Value="Yellow"/> </Style> </Application.Resources> </Application>
It has a code behind file too named as App.xaml.cs. This file is used to handle global application level events which you can use as per your need. Visual Studio creates these two files at the time of project creation. The three events inside the App.xaml.cs are:
These three events are registered in the constructor of your App.xaml.cs file. Here is the code snippet of the same:
public partial class App : Application { public App() { this.Startup += this.Application_Startup; this.Exit += this.Application_Exit; this.UnhandledException += this.Application_UnhandledException;
InitializeComponent(); } private void Application_Startup(object sender, StartupEventArgs e) { this.RootVisual = newMainPage(); } private void Application_Exit(object sender, EventArgs e) { } private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e) { if (!System.Diagnostics.Debugger.IsAttached) { e.Handled = true; Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); }); } } private void ReportErrorToDOM(ApplicationUnhandledExceptionEventArgs e) { try { string errorMsg = e.ExceptionObject.Message + e.ExceptionObject.StackTrace; errorMsg = errorMsg.Replace('"', '\'').Replace("\r\n", @"\n"); System.Windows.Browser.HtmlPage.Window.Eval("throw new Error(\"Unhandled Error in Silverlight Application " + errorMsg + "\");"); }
catch (Exception) { } } }
Inside the constructor of the App class you will find that all the three event has been registered. Also, there is a call to InitializeComponent() method. If you look around the whole class you will not find the method implementation. Strange!!! Where is the method? The method has been implemented inside the partial class of the App class. If you go to the definition or just press F12 on top of the method, Visual Studio will open up the actual file named App.g.i.cs which contains the partial implementation of the same class. There you will find the method implementation. What this method does: This method is responsible to load the XAML using the LoadComponent() method into the memory which can be used by your application. What can we do inside the App.g.i.cs file: App.g.i.cs file is auto generated by the compiler and hence if you modify something there will be overwritten by the compiler itself on next build. Why this file is not available inside my solution: As this is an compiler generated file, it has been placed inside the temporary directory named obj. If you go to the solution directory you will see the obj folder. Open it and browse through its subfolder (either debug or release) and you will see the file placed there. If you are unable to find it there, just do a rebuild of your solution and immediately it will be created there.
Overview of Application_Startup Event:
Application_Startup event is the root of your application. In this event you can create the instance of your initial page and set it as the RootVisual. Also, if you want to create some global objects or want to write some app initialization code, then this Application_Startup event will be the best part for you to implement it.
Overview of Application_Exit Event:
Similarly, you can write code to cleanup objects or do something when closing the application inside the Application_Exit event.
Overview of Application_UnhandledException Event:
If any exception comes while running and you didnt handle that in the actual place, you can write some code in Application_UnhandledException to log the error details into database or show some message to the user. This will allow the application to continue running after an exception has been thrown. By default, if the app is running outside of the debugger then report the exception using the Browser DOM & the error will be visible in the status bar of Internet Explorer.
Lets walk-through each lines of the code. It contains an UserControl as root of the file which may contain all other controls inside it. The following line tells the compiler to use the specified class to use:
x:Class="SilverlightApps.HelloSilverlight.MainPage"
The next couple of lines beginning with xmlns tells the compiler to import some namespaces which can be used by the Silverlight XAML page. The following line speaks about the design time Height & Width of the Silverlight page:
d:DesignHeight="300" d:DesignWidth="400"
If you want to specify actual Height & Width of your Silverlight application, you can manually append the following line inside that:
Height="300" Width="400"
Next comes the Grid control which is used as a layout panel and that can include more other controls. Though the default XAML file uses the Grid as the layout panel, you can change it to any other panel as per your need. I will discuss about the various panel later in this tutorial.
<Grid x:Name="LayoutRoot" Background="White"> </Grid>
MainPage.xaml has also its code behind file like App.xaml & you can use this to write code to develop your functionalities. By default, it comes empty with a call to Initialize() method inside the Constructor of the MainPage class. The implementation of this method is also available in a different partial class of MainPage inside MainPage.g.i.cs like App class. Whenever you add some controls inside the XAML page, it will be loaded here.
Silverlight Application (XAP) generally loads inside the ASPX or HTML pages pointing to the path to load the XAP. The aspx/html page uses <object /> tag to load the Silverlight application. Here is the code present inside the aspx/html pages for loading the Silverlight XAP:
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> <paramname="source" value="ClientBin/SilverlightApps.HelloSilverlight.xap"/> <paramname="onError" value="onSilverlightError" /> <paramname="background" value="white" /> <paramname="minRuntimeVersion" value="4.0.50222.0" /> <paramname="autoUpgrade" value="true" /> <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50222.0" style="text-decoration:none"> <imgsrc="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/> </a> </object>
In the first line <object> tag tells the browser to load the Silverlight plug-in. Next couple of lines uses <param> tag. o The first param source has the value to the location of the .xap file. o Second param onError tells the plug-in to call the javascript method mentioned in the value, if any application error occurs. o The third param background specifies the color of the Silverlight application background. o The next param minRuntimeVersion specifies the minimum required plug-in version to load your Silverlight application. o If autoUpgrade is set as true in the next param, it will automatically upgrade the runtime. The next lines are very interesting. Whatever you design there, will not be visible in the browser in normal scenarios. If the user doesnt have Silverlight runtime installed in his PC or the Silverlight plug-in is disabled this section will visible to the user. This part is well known as Silverlight Installation Experience panel. By default, it shows a Silverlight image to download the runtime from Microsoft site. When the user clicks on it, this starts the installation. I will discuss about the Silverlight Experience later in depth.
3. Expand the Visual C# node and then go to sub node Silverlight 4. Select Silverlight Application in the right pane
5. Select proper location to store your application (lets say, D:\Sample Apps\ 6. Now enter a proper name for your project (call it as: SilverlightApps.HelloSilverlight) 7. Select the .Net Framework version from the combo box at the top (I am using .Net Framework 4.0 by default as I am using Visual Studio 2010) and click OK 8. In the next dialog make sure that Host the Silverlight application in a new Web site option is selected
Wait for a while, Visual Studio will now create the first Silverlight solution for you to use which will contain a Silverlight Project and one Web Application Project to host your Silverlight application. Once done, you will see Visual Studio already created two XAML files (App.xaml & MainPage.xaml) for you inside the Silverlight Application project. So for now your first Silverlight application has been created. Press F5 to run the application. It will open a browser Window with a blank page on that. Wow! What happened? Nothing is there!!! Dont worry, everything is fine. We didnt modify the default blank XAML page. Just right click on the browser page & you will see the Silverlight context menu on that.
The main Silverlight project (SilverlightApps.HelloSilverlight) consists of App.xaml, App.xaml.cs, MainPage.xaml & MainPage.xaml.cs. I already discussed on those file in depth in previous chapter. The web project (SilverlightApps.HelloSilverlight.Web) consists of JavaScript file named Silverlight.js which is responsible for checking the Silverlight version in client side and also if the Silverlight plug-in is missing at the user end, it asks to install the required runtime from Microsoft site. The .aspx & .html pages are present in the root to host the Silverlight application. Your Silverlight application .xap file is located under the ClientBin directory inside the Web project.
1. Open the file MainPage.xaml in Visual Studio 2. Inside the Grid tag add the following texts:
<TextBlock x:Name="txtTitle" Text="Hello Silverlight From XAML" FontSize="32" Foreground="Red" HorizontalAlignment="Center"/>
3. Press F5 to run your application once again. Once the browser loads your Silverlight application you will see Hello SilverlightFrom XAML text appears inside the browser window.
Now, we will create the same from the code behind (programmatically). Assume that, we have not added the Text inside the XAML. 1. Open your MainPage.xaml.cs using the Visual Studio 2. There you will find the constructor of the MainPage class. Add the following lines of code after the call to the InitializeComponent() method:
// Create the instance of the textblock and set it's properties TextBlock txtTitle = new TextBlock { Name = "txtTitle", Text = "Hello Silverlight From Code", FontSize = 32.0, Foreground = new SolidColorBrush(Colors.Red), HorizontalAlignment = HorizontalAlignment.Center
Lets describe it in depth. First of all we are creating the instance of the TextBlock control and setting the Name, Text, FontSize, Foreground color etc. at the time of initialization. Then once the control is ready, we are adding it to the main panel i.e. the Grid layout panel inside the XAML named LayoutRoot. After adding this your code will look like below:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace SilverlightApps.HelloSilverlight { public partial class MainPage : UserControl { public MainPage() { InitializeComponent();
// Create the instance of the textblock and set it's properties TextBlock txtTitle = new TextBlock { Name = "txtTitle", Text = "Hello Silverlight From Code", FontSize = 32.0, Foreground = new SolidColorBrush(Colors.Red), HorizontalAlignment = HorizontalAlignment.Center }; // Add the textblock instance as the children of the "LayoutRoot" LayoutRoot.Children.Add(txtTitle); } } }
3. Press F5 to run your application. You will now see your browser window opens with a text Hello Silverlight From Code inside it.
Note that, the TextBlock control has been added as a child element to the LayoutRoot panel which is a Grid. So, the question here is, what are the panels available in Silverlight where we can add child controls? Ok, for now just remember that there are several content holders (panels) available to hold any child controls like: Grid, Canvas, Border, StackPanel etc. In XAML pages the elements are maintained in a hierarchy like the HTML pages (DOM i.e. Document Object Model). This hierarchy allows us to nest different controls inside each other. I will discuss on this in depth in the next chapter.
</UserControl>
Also, if you open the MainPage.xaml.cs file you will notice that the class itself inherits from the base class UserControl.
namespace SilverlightApps.HelloSilverlight { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } } }
So, what is that UserControl? UserControls are basic unit of reusable XAML like you use in asp.net. It is the root of your XAML and contain only one child as a control. Though that child may contain one or more other controls but the UserControl must have a maximum of one content control. UserControls are mainly created using XAML and then reused in various places. How can I create a simple new Silverlight UserControl? Is it difficult to implement? Ummm I will not tell you. Let us create a simple UserControl then. You will tell me whether it is difficult or simple.
Silverlight Tools for Visual Studio comes up with the default template for creating a basic UserControl. Now follow the steps to create it:
1. Open your existing Silverlight application project (for this example, you can use the HelloSilverlight project just now we created) 2. Right click on the Silverlight project SilverlightApps.HelloSilverlight and select Add -> New Item 3. Select Silverlight UserControl from the right panel
This will create the UserControl named EmployeeView with the default template layout and open up the XAML page in the IDE. If you look into the XAML code you will notice the following code:
We already discussed about each of the lines in the previous chapter (in What is MainPage.xaml file section). So, I will not cover it again. Now let us build our first UserControl to show the Employees FirstName, LastName& Department inside the UserControl XAML file. How to do that? Before doing it let us split our Grid panel into three Rows & two Columns (will discuss on this in next chapter):
<Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="100"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> </Grid>
Now, lets add the TextBlocks inside the Grid, in specific Rows and Columns. In our case the left column will hold the FirstName, LastName and Department label. The second column will hold the informations according to the labels. Here is the XAML code for the same:
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" Width="300"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="100"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TextBlock x:Name="LabelFirstName" Text="FirstName" Grid.Row="0" Grid.Column="0"/> <TextBlock x:Name="FirstName" Text="Kunal" Grid.Row="0" Grid.Column="1"/> <TextBlock x:Name="LabelLastName" Text="LastName" Grid.Row="1" Grid.Column="0"/> <TextBlock x:Name="LastName" Text="Chowdhury" Grid.Row="1" Grid.Column="1"/> <TextBlock x:Name="LabelDepartment" Text="Department" Grid.Row="2" Grid.Column="0"/> <TextBlock x:Name="Department" Text="Software Engineering" Grid.Row="2" Grid.Column="1"/> </Grid> </UserControl>
You can see, I am using Grid.Row and Grid.Column attributes in each TextBlock. What does it mean? Grid.Row specifies the row number where to place the control. Similarly, Grid.Column specifies the column number. For example, if you use Grid.Row=2 and Grid.Column=4 to any element inside your Grid, the element control will be placed in 3rd Row and 5th Column of the Grid. You can think the Grid panel as a Matrix which has zero based index. Our UserControl is ready now, but before running the application we need to put it inside the MainPage which loads at application load. You can do this in two different ways. One is using the XAML and the another is using the Code-behind file. In code behind it is very easy. You have to follow the same steps as we did in previous chapter to set the Hello Silverlight TextBlock, but if you want to set it in XAML you have to do a little trick for the first time. Let us discuss on this step-by-step:
First go with the Declarative Approach: 1. Open the file MainPage.xaml in Visual Studio 2. Add the following line inside the UserControl tag of the MainPage.xaml (after any xmlns line):
xmlns:uc="clr-namespace:SilverlightApps.HelloSilverlight"
Now, your MainPage.xaml will look like this (the bolder text I have inserted in the XAML):
<UserControl x:Class="SilverlightApps.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" xmlns:uc="clr-namespace:SilverlightApps.HelloSilverlight" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> </Grid> </UserControl>
Here, uc stands for pre-tag for specifying the namespace. You can use any name. We used uc to specify UserControl for better readability. Now inside the Grid control you can add the UserControl we have just created. Here is the code for the same:
Once you run your application now, you will see the following view of your first UserControl application:
Now let us create it from Code-behind. I assume that the control we just added inside the Grid has been removed from the XAML, that means your Grid panel has no child inside it. Create the instance of the EmployeeViewUserControl and add it as child to the LayoutRoot Grid:
// Create the instance of the EmployeeViewUserControl EmployeeView empView = new EmployeeView { Width = 300.0, Height = 60.0,
}; // Add the EmployeeViewUserControl as the child of the default panel "LayoutRoot" LayoutRoot.Children.Add(empView);
Run your application and you will see the same output. The second approach is easy, am I right? Yup, for the first application it looks very easy enough. But when you write complex applications you will notice that the first approach is easier than the later. Why? Because, you will get more control over the design. You can see the output immediately in the preview sceen, also you can drag the control to position it properly in the panel. In some cases you will find it useful from code. Depending upon your business need you have to decide where to create and add your UserControl. Is it confusing? No, when you are sure that you have to dynamically load no. of UserControls based on your data you have to create and load it from the code behind. For the other cases, it will be easier to write inside the XAML. Remember that, you can create as many instances of your UserControl and place it inside your XAML page. Once we discuss on the different types of panel and layout in next chapter you can get better visibility to that.
Overview of Panels
There are total six numbers of panels available in Silverlight. They are as below:
1. Grid 2. Canvas
3. 4. 5. 6.
You will find Grid, Canvas, StackPanel and Border as most useful panel while you start working with them in your Silverlight application. Let us discuss about those in depth.
Now lets discuss about creating rows and columns, then place some rectangles in each cells. We will create three rows and three columns as described in the above image: 1. Create a UserControl named GridPanelDemo in our Silverlight Application.
2. Open the GridPanelDemo.xaml file. You will see that there is a Grid named LayoutRoot inside your UserControl. 3. Now enter the following XAML code between the Grid tags (<Grid></Grid>):
<Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions>
4. This will divide your Grid in three rows and three columns of equal height and equal width. 5. You can also set height for Rows and widths for Columns by specifying the value to the properties like this:
<RowDefinition Height="100"/> and <ColumnDefinition Width="100"/>
6. You can specify the value for Height & Width in three different ways: a. Pixel Value (like: 90, means the height or width of 90 pixel) b. Percentage Value (like: 5*, means the height or width of 50% or *, means 100%) c. Automatic Value (like: Auto, means the height or width of the Row or Column will resize automatically as per the size of content of the respective Row or Column. 7. Now we will put some texts using TextBlock and will put them in appropriate cells of the Grid control. You can achieve this by using the Grid.Row=ROW_NUMBER and Grid.Column=COLUMN_NUMBER as the property of your TextBlock control. Modify your XAML to set this texts like this:
<Grid x:Name="LayoutRoot" Background="BlanchedAlmond">
<Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <TextBlock Text="Row[0], Col[0]" Grid.Row="0" Grid.Column="0" /> <TextBlock Text="Row[0], Col[1]" Grid.Row="0" Grid.Column="1" /> <TextBlock Text="Row[0], Col[2]" Grid.Row="0" Grid.Column="2" /> <TextBlock Text="Row[1], Col[0]" Grid.Row="1" Grid.Column="0" /> <TextBlock Text="Row[1], Col[1]" Grid.Row="1" Grid.Column="1" /> <TextBlock Text="Row[1], Col[2]" Grid.Row="1" Grid.Column="2" /> <TextBlock Text="Row[2], Col[0]" Grid.Row="2" Grid.Column="0" /> <TextBlock Text="Row[2], Col[1]" Grid.Row="2" Grid.Column="1" /> <TextBlock Text="Row[2], Col[2]" Grid.Row="2" Grid.Column="2" /> </Grid>
8. Also, you can use Grid.RowSpan and Grid.ColumnSpan properties to span your rows and columns. If you are familiar with HTML table tag & properties you can easily understand it properly.
<TextBlock Text="Row[0], Col[0]" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2" />
If we use the above code, it will span the 0th Row and 0th Column to two Rows & Columns. This is nothing but merging rows and columns of Grid Layout.
9. Now, open the MainPage.xaml.cs file & in the constructor create the instance of the GridPanelDemo usercontrol and add it as the child of the LayoutRoot i.e. Grid.
LayoutRoot.Children.Add(new GridPanelDemo());
10. Run your Silverlight application. You will see that, the TextBlocks are arranged in the Page in matrix manner.
You will find this useful when you have to position your controls in proper way, in proper Row & Column. Note that, if you dont create rows or columns and place multiple controls inside your naked Grid, you will see them overlapping each other. So, if you are using Grid be sure that you splitted your Grid in proper rows and columns.
Lets think there are two Rectangles placed inside the Canvas as mentioned in the above figure. The first Rectangle (Blue one) is placed at the (10, 10) position. This is the coordinate location of your first Rectangle. First one stands for Left and second one stands for Top. So, What is the coordinate position of the second Rectangle (Orange one)? Exactly, it is Left =50 and Top = 30 i.e. (50, 30). I think it is the right time to go for writing a sample code to create the above canvas with two Rectangles inside it. I am pretty much confident that, you have now a good confidence on the Canvas positioning. Let us create a new UserControl named CanvasPanelDemo and then we will create two Rectangles in it and will place it in proper location.
1. Create a UserControl named CanvasPanelDemo in our Silverlight Application. 2. Open the CanvasPanelDemo.xaml file. You will see that there is a Grid named LayoutRoot inside your UserControl. 3. Now replace your Grid tag (<Grid></Grid>) with a Canvas tag (<Canvas></Canvas) and set the background color as Green:
<Canvas Background="Green" > </Canvas>
4. Now, open your MainPage.xaml.cs file and modify your constructor to load the newly created CanvasPanelDemo Usercontrol in page load as a child to your LayoutRoot Grid:
LayoutRoot.Children.Add(new CanvasPanelDemo());
5. If you run your application now, you will see that your Canvas has taken the full screen of your browser window. Why? You didnt set the Height & Width of your UserControl and placed inside a Grid. Thats why it took the full size of the browser window and thats why you can see your Green canvas taking the whole screen. 6. We will now create two Rectangles and place it inside the Canvas. For the first time, we will not set any position to the rectangles. Lets see what happens then. Modify your XAML to look like this:
<Canvas Background="Green" > <Rectangle x:Name="rectFirst" Fill="Blue" Height="80" Width="120"/> <Rectangle x:Name="rectSecond" Fill="Orange" Height="100" Width="150"/> </Canvas>
7. If you run your application again, you will see only one Rectangle present inside your Canvas. Which one? Yes, only the orange one. So, there you will ask We added two Rectangle, one Green and another Orange. But why only the orange one is visible in the UI? What happened to the first rectangle? So, my answer will be Nothing happened to any of your added control. They all are placed inside the Canvas. Yes, thats right. All the two rectangles are available inside your canvas. As we didnt specify the position of the rectangles and the second rectangle is bigger than the first one, it placed on top of the other i.e. the orange one placed on top of the green rectangle. Whatever control you add at the end of the Canvas will have a higher Z-Index which places your control on top of the other. I will discuss on this later in this chapter.
8. Now, lets go for positioning the rectangles. We will set coordinate position (50, 50) to the first rectangle and coordinate position (200, 100) to the second rectangle. For doing this, we have to set the Canvas.Left and Canvas.Top properties of each Rectangle. Have a look into the following code. You will understand easily how to do this.
<Canvas Background="Green"> <Rectangle x:Name="rectFirst" Fill="Blue" Height="80" Width="120" Canvas.Left="50" Canvas.Top="50" /> <Rectangle x:Name="rectSecond" Fill="Orange" Height="100" Width="150" Canvas.Left="200" Canvas.Top="100" /> </Canvas>
9. Run your application and you will notice that the first rectangle has been placed at (Left=50, Top=50) location and the second one has been placed at (Left=200, Top=100) location. Your application will look similar to this:
10. Now if you want to play around it, just modify your XAML to place the rectangle controls in various positions inside the canvas.
I think you are now familiar with positioning silverlight controls inside the Canvas. Let us discuss something on the Z-Index property. Z-Index stands for layering out your Silverlight application. If you are familiar with Photoshop you knew that, photoshop creates layers to position them on top of each other. Those who dont know about it can learn it from here. Suppose you want to create an application where two rectangles are there (similar to the previous example) and one rectangle is partially blocking the another. You have to write a logic to modify your application such that, when you click on the first rectangle it will come front of the another. Similar kind of logic for the second rectangle too.
So, how can we develop this? We have to use the Z-Index property for each rectangle. Lets say we will set the Z-Index of the first rectangle to 1 (one) and the second rectangle to 2 (two). Initially the second rectangle is blocking the first one partially. Now once you click on the first rectangle we will set the Z-Index of it to 2 and the Z-Index of the other rectangle to 1. As the Z-Index of the first rectangle is greater than the second it will come on top of the other. The same behaviour will be for the second rectangle. Once we click on the second rectangle (which is hiding behind the first) will come top the other will go behind. For doing this, we will set the Z-Index of the first rectangle to 1 and the second to 2.
1. Open the CanvasPanelDemo.xaml file and modify the Rectangle properties of Canvas.Left and Canvas.Top to place the rectangle on top of each other. 2. Now add the Canvas.ZIndex property to each rectangle. Set it to 1 for the first rectangle and set it to 2 for the second rectangle. After these modifications your xaml will look like this:
<Canvas Background="Green"> <Rectangle x:Name="rectFirst" Fill="Blue" Height="80" Width="120" Canvas.Left="50" Canvas.Top="50" Canvas.ZIndex="1" /> <Rectangle x:Name="rectSecond" Fill="Orange" Height="100" Width="150" Canvas.Left="92" Canvas.Top="74" Canvas.ZIndex="2" /> </Canvas>
3. Run your Silverlight application and you will see them in action. You will see the orange rectangle blocking a part of the blue rectangle.
4. Now let us write some logic to code behind (C#) to change the ZIndex property of the rectangles. To do this, first we will register the MouseLeftButtonDown event of both the rectangles in the constructor:
public CanvasPanelDemo() { InitializeComponent(); rectFirst.MouseLeftButtonDown += (rectFirst_MouseLeftButtonDown); rectSecond.MouseLeftButtonDown += (rectSecond_MouseLeftButtonDown); }
5. Now in the MouseLeftButtonDown event of the first rectangle we will set the ZIndex of the first rectangle to 2 and the second rectangle to 1. This will cause the first rectangle to come on top of the second rectangle.
private void rectFirst_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Canvas.SetZIndex(rectFirst, 2); Canvas.SetZIndex(rectSecond, 1); }
6. In the MouseLeftButtonDown event of the second rectangle we will set the ZIndex of the first rectangle to 1 and the second rectangle to 2. This will cause the second rectangle to come on top of the first one.
private void rectSecond_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Canvas.SetZIndex(rectFirst, 1); Canvas.SetZIndex(rectSecond, 2); }
7. Run your application to see it in action. At the initial time the second rectangle will be on top of the first one. When you click on the first rectangle it will come in front. Once you click on the second rectangle the first will go behind and thus the second rectangle will come at the front.
Let us create an example to showcase the StackPanel demo: 1. Create a UserControl named StackPanelDemo in your Silverlight project
2. Now, open your MainPage.xaml.cs file and modify your constructor to load the newly created StackPanelDemo Usercontrol in page load as a child to your LayoutRoot Grid:
LayoutRoot.Children.Add(new StackPanelDemo());
3. Open the StackPanelDemo.xaml file and inside the Grid tag named LayoutRoot we will add two StackPanels (one Horizontal and another Vertical) with some Rectangles as Children. 4. The following XAML code will create a Vertical StackPanel which consists of four rectangles of different colors:
<StackPanel Orientation="Vertical" Background="SkyBlue" Height="200" Width="100" Grid.Column="0"> <Rectangle Height="50" Width="100" Fill="Red" /> <Rectangle Height="50" Width="100" Fill="Green" /> <Rectangle Height="50" Width="100" Fill="Blue" /> <Rectangle Height="50" Width="100" Fill="Yellow" /> </StackPanel>
5. The following code will create a Horizontal StackPanel which also contains four rectangles of different colors:
<StackPanel Orientation="Horizontal" Background="SkyBlue" Height="100" Width="300" Grid.Column="1"> <Rectangle Height="100" Width="60" Fill="Red" /> <Rectangle Height="100" Width="60" Fill="Green" /> <Rectangle Height="100" Width="60" Fill="Blue" /> <Rectangle Height="100" Width="60" Fill="Yellow" /> </StackPanel>
6. Now run your application and you will notice the following UI of your StackPanel Demo application. The left panel is your Vertical StackPanel whereas the right panel is the Horizontal StackPanel.
4. Add some more rectangles inside the StackPanel, so that, the ScrollBar got enabled for the ScrollViewer. After the modification of your XAML will look like this:
<ScrollViewer Height="200" Grid.Column="0"> <StackPanel Orientation="Vertical" Background="SkyBlue" Width="100"> <Rectangle Height="50" Width="100" Fill="Red" /> <Rectangle Height="50" Width="100" Fill="Green" /> <Rectangle Height="50" Width="100" Fill="Blue" /> <Rectangle Height="50" Width="100" Fill="Yellow" /> <Rectangle Height="50" Width="100" Fill="Red" /> <Rectangle Height="50" Width="100" Fill="Green" /> <Rectangle Height="50" Width="100" Fill="Blue" /> <Rectangle Height="50" Width="100" Fill="Yellow" /> <Rectangle Height="50" Width="100" Fill="Red" /> <Rectangle Height="50" Width="100" Fill="Green" /> <Rectangle Height="50" Width="100" Fill="Blue" /> <Rectangle Height="50" Width="100" Fill="Yellow" /> </StackPanel> </ScrollViewer>
5. If you run the application now, you will see a ScrollBar on the right side of the panel. Thus it make your Rectangles to scroll properly.
Here note that, we set the Height to the ScrollViewer and not to the StackPanel. The reason behind this is, if you set the Height of the StackPanel it will have a fix height, thus it will not create the Scrolling behaviour. As we set the Height to the ScrollViewer the StackPanel height increases as and when you add child to it but the ScrollViewer here does a great job and creates a scrollbar cropping the StackPanel to the height of the ScrollViewer.
After seeing the above figure, I think one question came to you mind that I can create the same thing using the Rectangle too. Then what is the benefit of using Border? Yes right. You can create the same thing using Rectangle too as we did earlier, but the main difference is You can create a rounded corner shape using Border. It has the property called CornerRadius. If you set it to 45, means your shape will have a corner radius of 45 degree. Let us create some borders in a demo application: 1. Create a UserControl named BorderDemo in your Silverlight project 2. Now, open your MainPage.xaml.cs file and modify your constructor to load the newly created BorderDemo Usercontrol in page load as a child to your LayoutRoot Grid:
LayoutRoot.Children.Add(new BorderDemo());
3. Open the BorderDemo.xaml file and inside the Grid tag named LayoutRoot we will add a Border as Content. 4. Let us add the first Border of Height=100 and Width=150 with a brown colored BorderThickness of 2:
5. Now we will modify this border to create a Rounded Corner border. To do this, we will add a property CornerRadius to it. We will set the value to 25 i.e. 25 degree. Your modified XAML will look like this:
<Border Height="100" Width="150" CornerRadius="25" BorderThickness="2" BorderBrush="Brown"/>
6. Now we will change it a little to set a background color to it. Border has a property called Background. You can set the color there which you like. Here is the modified XAML of the same:
<Border Height="100" Width="150" CornerRadius="25" BorderThickness="2" BorderBrush="Brown" Background="Brown"/>
If you run your Silverlight application now, you will see the following:
7. Let us modify it a little bit more to add a child inside it. We will put a Text I am a TextBlock inside Border control. Put the below code in your XAML. You will notice that I placed a TextBlock inside the <Border> </Border> tag. You can place any control or panel inside the Border like this.
<Border Height="100" Width="250" CornerRadius="25" BorderThickness="2" BorderBrush="Brown" Background="Brown"> <TextBlock Text="I am a TextBlock inside Border control" VerticalAlignment="Center" HorizontalAlignment="Center"/> </Border>
Remember that, you can add only one child to the Border panel. If you need to add more than one child, add a different panel like Grid, Canvas or StackPanel inside the Border and then add the child elements to that panel. Think before chosing your panels.
<Viewbox Stretch="Fill" MaxWidth="200" MaxHeight="200" Name="viewBox2"> <Image Source="images/microsoft_silverlight.jpg"/> </Viewbox> <Viewbox Stretch="Fill" MaxWidth="300" MaxHeight="300" Name="viewBox3"> <Image Source="images/microsoft_silverlight.jpg"/> </Viewbox>
//Set the Stretch property to Fill private void stretchFill(object sender, RoutedEventArgs e) { viewBox1.Stretch = Stretch.Fill; viewBox2.Stretch = Stretch.Fill; viewBox3.Stretch = Stretch.Fill; }
2. None: If you set the Stretch property to None, the content will preserve its original size.
<Viewbox Stretch="Fill" MaxWidth="100" MaxHeight="100" Name="viewBox1"> <Image Source="images/microsoft_silverlight.jpg"/> </Viewbox> <Viewbox Stretch="Fill" MaxWidth="200" MaxHeight="200" Name="viewBox2"> <Image Source="images/microsoft_silverlight.jpg"/> </Viewbox> <Viewbox Stretch="Fill" MaxWidth="300" MaxHeight="300" Name="viewBox3"> <Image Source="images/microsoft_silverlight.jpg"/> </Viewbox> //Set the Stretch property to None private void stretchNone(object sender, RoutedEventArgs e) { viewBox1.Stretch = Stretch.None; viewBox2.Stretch = Stretch.None; viewBox3.Stretch = Stretch.None; }
3. Uniform: If you set the Stretch property to Uniform, the content will resize to fit the ViewBox. The ViewBox will take as much space as require to show the entire content and also preserves the aspect ratio.
<Viewbox Stretch="Fill" MaxWidth="100" MaxHeight="100" Name="viewBox1"> <Image Source="images/microsoft_silverlight.jpg"/> </Viewbox> <Viewbox Stretch="Fill" MaxWidth="200" MaxHeight="200" Name="viewBox2"> <Image Source="images/microsoft_silverlight.jpg"/> </Viewbox> <Viewbox Stretch="Fill" MaxWidth="300" MaxHeight="300" Name="viewBox3"> <Image Source="images/microsoft_silverlight.jpg"/> </Viewbox> //Set the Stretch property to Uniform
private void stretchNone(object sender, RoutedEventArgs e) { viewBox1.Stretch = Stretch.Uniform; viewBox2.Stretch = Stretch.Uniform; viewBox3.Stretch = Stretch.Uniform; }
4. UniformToFill: If you set the Stretch property to UniformToFill, the content will resize to fill the destination dimension. If the original size differs than the aspect ratio of the ViewBox, the content is then clipped to fit the ViewBox dimension.
<Viewbox Stretch="Fill" MaxWidth="100" MaxHeight="100" Name="viewBox1"> <Image Source="images/microsoft_silverlight.jpg"/> </Viewbox>
<Viewbox Stretch="Fill" MaxWidth="200" MaxHeight="200" Name="viewBox2"> <Image Source="images/microsoft_silverlight.jpg"/> </Viewbox> <Viewbox Stretch="Fill" MaxWidth="300" MaxHeight="300" Name="viewBox3"> <Image Source="images/microsoft_silverlight.jpg"/> </Viewbox> //Set the Stretch property to UniformToFill private void stretchNone(object sender, RoutedEventArgs e) { viewBox1.Stretch = Stretch.UniformToFill; viewBox2.Stretch = Stretch.UniformToFill; viewBox3.Stretch = Stretch.UniformToFill; }