다음을 통해 공유


Quickstart: Creating a user interface with XAML for Windows Phone 8

[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]

Extensible Application Markup Language (XAML) is used to define the Windows Phone user interface. XAML is a declarative language that you can use to create app UI such as controls, shapes, text, and other Windows Phone screen content. XAML comprised of elements and attributes similar to those used in HTML. XAML however is XML-based and therefore must follow XML rules, which include being well formed. You might ask, "Why do I care about XAML if I'm just going to use tools like Visual Studio or Blend for Visual Studio to create the UI?" Even though there are tools that generate markup, you'll invariably 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 topic contains the following sections.

XAML example

The following is a simple XAML example that creates a button.

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
   <Button Height="72" Width="160" Content="Click Me" />
</Grid>

When you run the app, it will look something like this:

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 Windows Phone app in Visual Studio, and is used to position objects. To learn more about screen layout, see Layout for Windows Phone 8.

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.)

<Grid x:Name="ContentGrid" Grid.Row="1">
   <Button Content="Button" Height="72" HorizontalAlignment="Left" Margin="152,273,0,0" Name="button1" VerticalAlignment="Top" Width="160" />
</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 by 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 app 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 they often are), 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.

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
   <Button Height="72" Width="160" Content="Click Me" />
</Grid>

The following shows how this XAML could be written in C# or Visual Basic

// Initialize the button
Button myButton = new Button();
// Set its properties
myButton.Width = 160;
myButton.Height = 72;
myButton.Content = "Click Me";
// Attach it to the visual tree, specifically as a child of
// the Grid object (named 'ContentPanel'). In other words, position
// the button in the UI.
ContentPanel.Children.Add(myButton);
' Initialize the button
Dim myButton As New Button()' Set its properties
myButton.Width = 160
myButton.Height = 72
myButton.Content = "Click Me"
'Attach it to the visual tree, specifically as a child of 
'the Grid object (named 'ContentPanel'). In other words, position
'the button in the UI.
ContentPanel.Children.Add(myButton)

For UI, XAML has the advantage of being easier to read and more compact than procedural 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

Attribute element syntax is the attribute="value" syntax that you've seen in the examples above and that you might be familiar with from HTML. In the following example, a red Rectangle is created. Fill is an attribute that is set to a predefined color name.

<Rectangle Fill="Red" />

Alternatively, you could specify the color value by using property element syntax.

<Rectangle>
   <Rectangle.Fill>
      <SolidColorBrush Color="Red" />
   </Rectangle.Fill>
</Rectangle>

In this case, you're 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 by 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'll likely need to use property element syntax. The following example creates a Rectangle, but instead of a simple red fill, it uses a gradient.

<!-- This rectangle is painted with a diagonal linear gradient. -->
<Rectangle Width="200" Height="200">
   <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>

When you run the app, it will look something like this:

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-initiated events. Consider the following example.

When you run the app, it will look something like this:

<Grid x:Name="ContentPanel" Background="Red" Grid.Row="1" Margin="12,0,12,0">
   <StackPanel Margin="20" Background="Blue" >
      <TextBlock Name="firstTextBlock" FontSize="30">First TextBlock</TextBlock>
      <TextBlock Name="secondTextBlock" FontSize="30">Second TextBlock</TextBlock>
      <TextBlock Name="thirdTextBlock" FontSize="30">Third TextBlock</TextBlock>
   </StackPanel>
</Grid>

The blue 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 among 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.

<Grid Background="Red" x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
   <StackPanel Margin="20" Background="Blue" MouseLeftButtonDown="commonMouseHandler">
      <TextBlock Name="firstTextBlock" FontSize="30" >First TextBlock</TextBlock>
      <TextBlock Name="secondTextBlock" FontSize="30" >Second TextBlock</TextBlock>
      <TextBlock Name="thirdTextBlock" FontSize="30" >Third TextBlock</TextBlock>
   </StackPanel>
</Grid>

The following shows the procedural code to handle the event.

private void commonMouseHandler(object sender, RoutedEventArgs e){
   FrameworkElement feSource = e.OriginalSource as FrameworkElement;
   switch (feSource.Name)
   {        
      case "firstTextBlock":
         firstTextBlock.Text = firstTextBlock.Text + " Click!";
         break;
      case "secondTextBlock":
         secondTextBlock.Text = secondTextBlock.Text + " Click!";
         break;
      case "thirdTextBlock":
         thirdTextBlock.Text = thirdTextBlock.Text + " Click!";
         break;  
   }
}
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 & " Click!"
      Case "secondTextBlock"
         secondTextBlock.Text = secondTextBlock.Text & " Click!"
      Case "thirdTextBlock"
         thirdTextBlock.Text = thirdTextBlock.Text & " Click!"
   End Select
End Sub

The following diagram shows how an event bubbles up the tree.

For example, let’s say that the user clicks the TextBlock.

  1. The MouseLeftButtonDown event bubbles up to the parent StackPanel.

  2. Next, the MouseLeftButtonDown event bubbles up the tree to the Grid.

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. Here's an example of a simple animation created with 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>
// When the user clicks the rectangle, the animation begins.
private void Mouse_Clicked(object sender, MouseEventArgs e){
   myStoryboard.Begin();
}
' When the user clicks the rectangle, the animation begins.
Private Sub Mouse_Clicked(ByVal sender As Object, ByVal e As MouseEventArgs)
   myStoryboard.Begin
End Sub

This 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.

See Also

Other Resources

Layout for Windows Phone 8