XAML
By Microsoft Silverlight Team|June 20, 2010|Level 100 : Beginner
Summary
XAML is a declarative language used in Silverlight to create UI, such as controls, shapes, text, and other content presented on the screen. If you're familiar with Web programming, you can think of XAML as similar to HTML, but more powerful. Like HTML, XAML is made up of elements and attributes. However, XAML is XML-based and therefore must follow XML rules, which includes being well formed. You might ask "Why do I care about XAML if I'm just going to use tools like Visual Studio or Expression Blend to create the UI?" Even though there are tools that generate markup, you are invariably going to want to go under the covers to understand or tweak the XAML. Besides, sometimes it's just easier to code UI by hand when you want fine control or just want to know what's going on.
This QuickStart contains the following sections:XAML Example
The following is a simple XAML example that creates a button.XAML
<Grid x:Name="LayoutRoot" Background="White"> <Button Width="60" Height="30">Click Me</Button> </Grid>The Button control is specified by the <Button> element. The Width and Height attributes specify the size of the button. The <Grid> is generated when you create a new Silverlight project and is used to position objects. To learn more about Silverlight layout, see the Layout QuickStart.
You can use Visual Studio to generate the XAML. For example, you can drag a button from the Toolbox to the design surface.
The following shows the XAML that Visual Studio might generate. (Your XAML might look different.)
XAML
<Grid x:Name="LayoutRoot" Background="White"> <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="158,125,0,0" Name="button1" VerticalAlignment="Top" Width="75" /> </Grid>Notice that Visual Studio adds some extra attributes, such as HorizontalAlignment and Margin, to position the button. This extra "plumbing" may not be desirable if your needs are very specific. Of course you can change these attributes using the Visual Studio UI, but in some cases, you might prefer to just edit the XAML directly.
One of the best things about using a declarative language like XAML is having a clean separation between the markup that makes up the UI and the code that makes the application do something. For example, a designer on your team could design a UI experience and then hand off the XAML to the developer to add the procedural code. Even if the designer and the developer are the same person (as it often is), you can keep your UI in XAML files (.xaml) and your procedural code in code-behind files (.cs and .vb).
XAML is Just Procedural Code (Only Easier)
XAML elements, like <Button />, are the equivalent of instantiating objects in procedural code. For example, consider the following XAML.XAML
<Grid x:Name="LayoutRoot" Background="White"> <Button Width="60" Height="30">Click Me</Button> </Grid>The following shows how this XAML could be written in C# or Visual Basic.
C#
// Initialize the button Button myButton = new Button(); // Set its properties myButton.Width = 60; myButton.Height = 30; myButton.Content = "Click Me"; // Attach it to the visual tree, specifically as a child of // the Grid object (named 'LayoutRoot'). In other words, position // the button in the UI. LayoutRoot.Children.Add(myButton);
Visual Basic
' Initialize the button Dim myButton As New Button() ' Set its properties myButton.Width = 60 myButton.Height = 30 myButton.Content = "Click Me" ' Attach it to the visual tree, specifically as a child of ' the Grid object (named 'LayoutRoot'). In other words, position ' the button in the UI. LayoutRoot.Children.Add(myButton)For UI, XAML has the advantage of being easier to read and more compact than procedural code. You typically do not create the UI in code. However, it's sometimes necessary to use procedural code to create UI dynamically.
Properties
The following are two ways to specify property values in XAML.- Attribute element syntax
- Property element syntax
XAML
<Rectangle Fill="Red">Alternatively, you could specify the color value using property element syntax like the following.
XAML
<Rectangle> <Rectangle.Fill> <SolidColorBrush Color="Red" /> </Rectangle.Fill> </Rectangle>In this case, you are explicitly specifying the SolidColorBrush object that is the type required by the Fill property rather than just using the string "Red". From this example, you might deduce that property element syntax is just a verbose way to do the same thing. However, not all property values can be specified using a simple attribute string. For example, if you need to specify multiple properties of an object used as the value of a property, you will likely need to use property element syntax. The following example creates a Rectangle, but instead of a simple red fill, it uses a gradient.
XAML
<!-- This rectangle is painted with a diagonal linear gradient. --> <Rectangle Width="200" Height="100"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> <GradientStop Color="Yellow" Offset="0.0" /> <GradientStop Color="Red" Offset="0.25" /> <GradientStop Color="Blue" Offset="0.75" /> <GradientStop Color="LimeGreen" Offset="1.0" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle>As you can see, the Fill property uses a complex object (LinearGradientBrush) to create the gradient. In cases like these, you need to use the property element syntax rather than simply specifying the value as a string assigned to an attribute.
XAML and the Visual Tree
In XAML, you have elements (such as <Button> and <Grid>) that can have other elements (nodes) underneath them (children). This parent/child relationship specifies things like how objects are positioned on the screen and how they respond to user-initated events. Consider the following example.XAML
<Grid x:Name="LayoutRoot" Background="Red"> <StackPanel Margin="20" Background="Yellow" > <TextBlock Name="firstTextBlock" Width="Auto" >First TextBlock</TextBlock> <TextBlock Name="secondTextBlock" Width="Auto" >Second TextBlock</TextBlock> <TextBlock Name="thirdTextBlock" Width="Auto" >Third TextBlock</TextBlock> </StackPanel> </Grid>The yellow StackPanel is contained within a red Grid. The TextBlock elements are contained within the StackPanel (TextBlock elements are children of StackPanel). In addition, the TextBlock elements are stacked on top of one another in the order they are declared in XAML.
The following tree diagram shows the relationships between elements.
Besides determining how content is presented, the visual tree also can have an effect on how events are processed. Many typical events (called routed events) "bubble" events up the tree. For example, you can attach an event handler to the StackPanel that handles when the left mouse button is clicked (MouseLeftButtonDown event). The following XAML shows how to add a MouseLeftButtonDown event handler named
commonMouseHandler to the StackPanel.XAML
<Grid x:Name="LayoutRoot" Background="Red"> <StackPanel Margin="20" Background="Yellow" MouseLeftButtonDown="commonMouseHandler" > <TextBlock Name="firstTextBlock" Width="Auto" >First TextBlock</TextBlock> <TextBlock Name="secondTextBlock" Width="Auto" >Second TextBlock</TextBlock> <TextBlock Name="thirdTextBlock" Width="Auto" >Third TextBlock</TextBlock> </StackPanel> </Grid>The following shows the procedural code to handle the event.
C#
private void commonMouseHandler(object sender, RoutedEventArgs e) { FrameworkElement feSource = e.OriginalSource as FrameworkElement; switch (feSource.Name) { case "firstTextBlock": firstTextBlock.Text = firstTextBlock.Text + " Thanks for the click!"; break; case "secondTextBlock": secondTextBlock.Text = secondTextBlock.Text + " Thanks for the click!"; break; case "thirdTextBlock": thirdTextBlock.Text = thirdTextBlock.Text + " Thanks for the click!"; break; } }
Visual Basic
Private Sub commonMouseHandler(ByVal sender As System.Object, _ByVal e As System.Windows.Input.MouseButtonEventArgs) Dim feSource As FrameworkElement = e.OriginalSource Select Case feSource.Name Case "firstTextBlock" firstTextBlock.Text = firstTextBlock.Text & " Thanks for the click!" Case "secondTextBlock" secondTextBlock.Text = secondTextBlock.Text & " Thanks for the click!" Case "thirdTextBlock" thirdTextBlock.Text = thirdTextBlock.Text & " Thanks for the click!" End Select End SubTo try this example, click the following TextBlock objects. When you click a TextBlock, the event gets captured by the TextBlock, but then the event bubbles up to its parent element (the StackPanel), which then handles the event.
The following diagram shows how the event bubbles up the tree.
Because the event continues up the tree, you could "listen" for the MouseLeftButtonDown event in the Grid element as well.
More than Static UI
You can do more than display static UI with XAML. You can create animations, embed video, and bind to data by just using markup. You will learn more about these uses of XAML in other QuickStarts; however, here's an example of a simple animation coded with XAML. To try this example, click the Rectangle to see the effect.XAML
<StackPanel Background="#FDF5E6"> <StackPanel.Resources> <Storyboard x:Name="myStoryboard"> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="myRectangle" Storyboard.TargetProperty="Height"> <!-- This key frame resets the animation to its starting value (30) at the beginning of the animation. --> <LinearDoubleKeyFrame Value="30" KeyTime="0:0:0" /> <!-- Spline animations are used to create acceleration. This SplineDoubleKeyFrame creates an animation that starts out slow and then speeds up. The rectangle "falls". --> <SplineDoubleKeyFrame KeySpline="0,0 1,0" Value="300" KeyTime="0:0:0.8" /> <!-- This spline animation creates the "bounce" at the end where the rectangle shortens its length quickly at first and then slows down and stops. --> <SplineDoubleKeyFrame KeySpline="0.10, 0.21 0.00, 1.0" Value="250" KeyTime="0:0:1.5" /> </DoubleAnimationUsingKeyFrames> </Storyboard> </StackPanel.Resources> <Rectangle x:Name="myRectangle" MouseLeftButtonDown="Mouse_Clicked" Fill="Blue" Width="200" Height="30" /> </StackPanel>
C#
// When the user clicks the rectangle, the animation // begins. private void Mouse_Clicked(object sender, MouseEventArgs e) { myStoryboard.Begin(); }
Visual Basic
' When the user clicks the rectangle, the animation ' begins. Private Sub Mouse_Clicked(ByVal sender As Object, ByVal e As MouseEventArgs) myStoryboard.BeginEnd SubThis is an example of using XAML to specify behavior of content rather than layout or other static UI. The Storyboard element defines some general properties of the animation, such as what object is to be animated. The child elements of Storyboard, such as LinearDoubleKeyFrame, specify how the animation executes. To learn more about animations, see Silverlight Animations.