What Is XAML?
XAML is the acronym for Extensible Application Markup Language. It’s a markup language based on XML, and its purpose and philosophy are very similar to HTML. Every control that can be placed on a page, whether a button, text box, or custom controls, is identified by a specific XML tag. Like XML, the structure is hierarchical; you can place tags inside other tags. For example, this hierarchical structure is how you can define the layout of a page, thanks to some controls that act as a container for other controls, like Grid or StackPanel.
The following is a sample of the XAML that defines a Windows Phone page:
PhoneApplicationPage is the base class of a Windows Phone page. As you can see, every other control is placed inside it. Notice also the x:Class attribute; it identifies which is the code-behind class that is connected to this page. In this sample, the code that is able to interact with the page will be stored in a class called MainPage that is part of the FirstApp namespace. We can see this class simply by clicking on the black arrow near the XAML file in Solution Explorer. You’ll see another file with the same name of the XAML one plus the .cs extension.
Let’s begin analyzing this simple XAML to introduce some key concepts, like namespaces and resources.
Namespaces
You should already be familiar with namespaces; they’re a way to structure your code by assigning a logical path to your class.
By default, Visual Studio assigns namespaces using the same folder structure of the project. This means that if, for example, you have a class called MyClass stored inside a file in the Classes folder, the default full namespace of your class will be Classes.MyClass.
Namespaces in XAML work exactly the same way. The XAML controls are, in the end, classes that are part of your project, so you have to tell the page where it can find them. In the standard page you can see many examples of namespace declarations:
Every namespace starts with the xmlns prefix, which is the standard XML namespace, followed by a custom prefix (in this sample it’s phone). This prefix is very important, because it’s the one that we’re going to use in the rest of the page to add the controls. Then, we define the full namespace that contains the controls. If the class is part of our project, it’s enough to specify just the namespace; otherwise, we also need to define which assembly (that is the DLL’s name) contains the class.
In the previous example, we want to include controls and resources in our page that are defined inside the Microsoft.Phone.Controls namespace, which is included in the Microsoft.Phone.dll library.
The PhoneApplicationPage class gives you an example of how to use a namespace. Since the PhoneApplicationPage class is part of the Microsoft.Phone.Controls namespace, we have to add the prefix phone to the tag to use it:
It’s very important to understand how namespaces in XAML work, because we’ll need to declare them every time we use third-party controls (that we created on our own or are part of an external library) or resources, like converters.
Properties and Events
Every control can be customized in two ways: by setting properties and actions. Both are identified by attributes of the XAML tag, but they have two different purposes.
Properties are used to change the look or the behavior of the control. Usually, a property is simply set by assigning a value to the specific attribute. For example, if we want to assign a value to the Text property of a TextBlock control, we can do it in the following way:
There’s also an extended syntax that can be used in the case of a complex property that can’t be defined with a plain string. For example, if we need to set an image as a control’s background, we need to use the following code:
Complex properties are set by using a nested tag with the name of the control plus the name of the property, separated by a dot (to set the Background property of the Grid control, we use the Grid.Background syntax).
One important property that is shared by every control is x:Name, which is a string that univocally identifies the control in the page. You can’t have two controls with the same name in a single page. Setting this property is very important if you need to interact with the control in the code behind—you’ll be able to refer to it by using its name.
Events are a way to manage user interactions with the control. One of the most used is Tap, which is triggered when users tap the control.
When you define an action, Visual Studio will automatically prompt you to create an event handler, which is the method (declared in the code behind) that is executed when the event is triggered.
In the previous example, we display the classic “Hello world” message to users when the button is pressed.
Resources
As in HTML, we are able to define CSS styles that can be reused in different parts of the website or the page. XAML has introduced the concept of resources that can be applied to different controls in an application.
Basically every XAML control supports the Resources tag: thanks to the hierarchy structure, every other nested control will be able to use it. In the real world, there are two common places to define a resource: at page and application level.
Page resources are defined in a single page and are available to all the controls that are part of that page. They are placed in a specific property called Resources of the PhoneApplicationPage class.
Application resources, instead, are globally available and they can be used inside any page of the application. They are defined in the App.xaml file, and the standard template already includes the needed definition.
Every resource is univocally identified by a name that is assigned using the x:Key property. To apply a resource to a control, we need to introduce the concept of markup extensions. These are special extensions that allow us to apply different behaviors that would otherwise need some code to properly work. There are many markup extensions in the XAML world, and the one needed to apply a resource is called StaticResource. Here is an example of how to use it:
In this sample, the resource is applied to the Style property by including the StaticResource keyword inside braces, followed by the resource name which is the value of the x:Key property.
Resources can be also defined in an external file called ResourceDictionary if you want to better organize your project. To do this, right-click on your project in Visual Studio, click Add > New Item, and choose XML file. Give the file a name that ends with the .xaml extension and include the following definition:
Now you can add it to your project by declaring it in the App.xaml:
Notice the MergedDictionaries property: all the external resource files should be declared here. This way, they will be automatically merged and every resource declared in each external file will be available to every page, as if they were declared inline.
Let’s see now, in detail, which are the most important kind of resources available.
Styles
XAML styles work the same way as CSS styles: you can define the values of different properties together in a single style that can be applied to multiple controls so that they all use the same layout. Here is how a style definition looks:
A style is defined by a Style tag, which has two important attributes: x:Key, the name of the style, and TargetType, the type of controls that will be suitable for this style.
Inside the Style tag you can place as many Setter tags as you want. Each one identifies a control’s property you want to change. Every Setter tag needs two attributes: Property is the control’s property you want to change, and Value is the value you want to assign to the property.
The style defined in the previous example can be applied to any TextBlock control. Its purpose is to change the size of the font to 24 and to apply a bold style to the text.
There are also special types of styles called implicit styles. They are defined in the same way as the styles in the earlier example, except that the x:Key attribute is missing. In this case, the style is automatically applied to every control that is compliant with the value of the TargetType property, according to the scope where the style has been defined. If the style is set as a page resource, it will be applied only to the controls of the page; if the style is set as an application resource, it will be applied to every control in the application.
Data Templates
Data templates are a special type of resource that can be applied to a control to define its appearance. Data templates are often used with controls that are able to display collections of elements, like ListBox or LongListSelector.
The following sample shows a data template:
A data template simply contains the XAML that will be used to render the specific item. If, for example, we apply this data template to the ItemTemplate property of a ListBox control, the result will be that the defined XAML will be repeated for every item in the collection (for the moment, just ignore the Binding markup extension; we’ll deal with it later when we talk about data binding).
As for every other resource, data templates can be assigned to a property using the StaticResource markup extension.
Animations
XAML is a powerful language because it allows us to do more than just create the layout of applications. One of the most interesting features is the animation feature, which can be created using the Storyboard control.
The Storyboard control can be used to define different types of animations:
DoubleAnimation, which can be used to change the numeric value of a property (for example, Width or FontSize).
ColorAnimation, which can be used to interact with properties that define a color (like inside a SolidColorBrush).
PointAnimation, which can be applied to properties that define a point coordinate.
The following sample code defines an animation:
The first two properties are inherited from the Storyboard control: Storyboard.TargetName is used to set the name of the control we’re going to animate, while Storyboard.TargetProperty is the property whose value we’re going to change during the animation.
Next, we define the animation’s behavior: the initial value (the From property), the ending value (the To property) and the duration (the Duration property). The behavior defined in the previous sample animates a Rectangle control by increasing its width from 200 to 400 over 4 seconds.
We can also control the animation more deeply by using the UsingKeyFrames variant available for every animation type:
This way you’re able to control the animation’s timing. In the previous sample, the animation’s type is the same (it’s a DoubleAnimation), but we’re able to set, for a specific time, which is the value to apply using the LinearDoubleKeyFrame tag.
In the previous sample, the Width of the Rectangle control is set to 200 at the beginning. Then, after two seconds, it increases to 250 and after four seconds, it is set to 500.
Easing Animations
Another way to create animations is to use mathematical formulas that are able to apply a realistic behavior to an object, like bouncing, or acceleration and deceleration. You could achieve the same result by using key frames, but it would require a lot of work. For this reason, the animation framework offers a set of predefined easing functions that can be easily applied to an animation.
To add an easing function, you just need to set the EasingFunction property of an animation, as shown in the following sample:
After you’ve defined a regular animation (in the example, it’s a PointAnimation that moves an Ellipse object from the coordinates (0, 0) to (0, 200)), you can set the EasingFunction property with one of the available easing functions. This example shows how to use the BounceEase function, which can be used to apply a bouncing effect to the object (the number of bounces performed is specified with the Bounces property).
Other available easing functions are:
BackEase, which retracts the motion of the animation slightly before it starts.
CircleEase, which applies a circular function to the acceleration animation.
ElasticEase, which creates an animation that resembles an oscillating spring.
The official MSDN documentation features a complete list of the available easing functions.
How To Control Animations
Animations are treated like resources. They can be defined as local resources, page resources, or application resources. Unlike traditional resources, Storyboard controls are identified by the x:Name property, like a regular control.
The following sample shows an animation that is set as a page resource:
Thanks to the unique identifier, you’ll be able to control the animation in the code behind. Every Storyboard object offers many methods to control it, like Begin(), Stop(), or Resume(). In the following code you can see the event handlers assigned to two buttons that are used to start and stop the animation:
Data Binding
Data binding is one of the most powerful features provided by XAML. With data binding, you’ll be able to create a communication channel between a UI element and various data sources, which can be another control or a property in one of your classes. Moreover, data binding is heavily connected to the XAML notification system (which we’ll detail later) so that every time you change something in your object, the control displaying it will be automatically updated to reflect the changes and display the new value.
When you create a communication channel using data binding, you define a source (which contains the data to display) and a target (which takes care of displaying the value). By default, the binding channel is set to OneWay mode. This means that when the source changes, the target is updated to display the new value, but not vice versa. If we need to create a two-way communication channel (for example, because the target is a TextBox control and we need to intercept a new value inserted by the user), we can set the Mode property of the binding to TwoWay.
Almost every control in the XAML can participate in data binding. Most of the properties available for a control, in fact, are dependency properties. Beyond offering basic read and write capabilities, these are special properties that support notifications, so that they can notify the other side of the channel that something has changed.
The following example shows how data binding can be used to create a channel between two XAML controls:
The first thing to notice is that to apply binding, we need to use another markup extension, called Binding. With this expression, we connect the Text property of a TextBlock control (the target) to the Value property of a Slider control named Volume (the source).
Since both Text and Value are dependent properties, every time you move the slider, the selected value will be automatically displayed on the screen in the TextBlock control.
Data Binding With Objects
One of the most powerful data binding features is the ability to connect controls with objects that are part of your code. However, first, we need to introduce the DataContext concept. DataContext is a property that is available for almost every control and can be used to define its binding context, which is also automatically inherited by every nested control. When you define an object as DataContext, the control and all its children will have access to all its properties.
Let’s see an example that will help you better understand how it works. Let’s say that you have a class that represents a person:
Our goal is to display information about a person using this class. Here is how we can do it using data binding. First, let’s take a look at the code behind:
When the page is initialized, we create a new Person object and set a value for the Name and Surname properties. Then, we set this new object as DataContext of the Author control. Let’s see in the XAML page the Author control and how the Name and Surname properties are displayed:
Author is the name assigned to a StackPanel control, which is the container we’ve placed inside different TextBlock controls. In the previous sample we can see the Binding markup extension in action again, this time with a different attribute: Path. We’re using it to tell the XAML which property of the current DataContext to display. Since the DataContext is inherited from the StackPanel control, every TextBlock has access to the properties of the Person object we’ve created in the code behind. Notice that the Path attribute is optional. The two following statements are exactly the same:
The INotifyPropertyChanged Interface
The previous code has a flaw. Everything works fine, but if you change the value of one of the Name or Surname properties during the execution, the user interface won’t be updated to display the new value. The reason is that Name and Surname are simple properties, so they aren’t able to notify the user interface that something has changed, unlike dependency properties. For this scenario, the XAML framework has introduced the INotifyPropertyChanged interface that can be implemented by objects that need to satisfy this notification requirement. Here is how the Person class can be changed to implement this interface:
The class now implements the INotifyPropertyChanged interface, allowing us to support an event handler (called PropertyChangedEventHandler) that is triggered every time a property’s value changes. The class also implements a method called OnPropertyChanged() that acts as a wrapper of the event handler and needs to be invoked when a property changes.
We also need a change in our properties. Every time the set of the property is called (meaning that a new value has been assigned) we raise the OnPropertyChanged() method. The result will be that every control bound with the property will be notified of the change and will update its visual status accordingly.
Data Binding and Collections
Data binding is especially helpful when you have to deal with collections of objects like arrays or lists (basically, every framework’s collection types that implement the IEnumerable interface). Almost every control that supports collections, which inherit from the ItemsControl class (like ListBox or LongListSelector), has a property called ItemsSource, which can be directly assigned to a list.
You can control how every object of the collection will be rendered by using the ItemTemplate property. As we’ve seen when we talked about data templates, this property allows us to set which XAML to use to display the object.
Now that we’ve talked about data binding, there’s another important piece to add. In the sample code we used to show data templates, we included some binding expressions to display the name and surname of a person.
When you set a collection as ItemSource, every object that is part of it becomes the DataContext of the ItemTemplate. If, for example, the ItemsSource property of a ListBox is connected to a collection whose type is List<Person>, the controls included in the ItemTemplate will be able to access all the properties of the Person class.
This is the real meaning of the previous sample code: for every Person object that is part of the collection, we’re going to display the values of the Name and Surname properties.
Another important piece of the puzzle when you deal with collections is the ObservableCollection<T> class. It acts like a regular collection, so you can easily add, remove, and move objects. Under the hood, it implements the INotifyPropertyChanged interface so that every time the collection is changed, the UI receives a notification. This way, every time we manipulate the collection (for example, we add a new item), the control that is connected to it will automatically be updated to reflect the changes.
Converters
Converters play an important role in data binding. Sometimes, in fact, you need to modify the source data before it is sent to the target. A common example is when you have to deal with DateTime properties. The DateTime class contains a full representation of a date, including hours, minutes, seconds, and milliseconds. Most of the time, however, you don’t need to display the full representation—often the date is just enough.
This is where converters come in handy. You are able to change the data (or, as shown in the following example, apply different formatting) before sending it to the control that is going to display it using data binding.
To create a converter, you need to add a new class to your project (right-click in Visual Studio, choose Add > Class), and it has to inherit from the IValueConverter interface. The following is a converter sample:
When you support the IValueConverter interface, you are forced to implement two methods:
Convert() is the method invoked when data from the source is sent to the target.
ConvertBack() does the opposite—it is invoked when data from the target is sent back to the source.
Most of the time it’s enough to implement the Convert() method that is supported by every binding. The ConvertBack() method, instead, is supported only when you have TwoWay binding.
Both methods receive some important information as input parameters:
The value returned from the binding source (which is the one you need to manipulate).
The property that the binding has been applied to.
An optional parameter that can be set in XAML using the ConverterParameter property. This parameter can be used to apply a different behavior in the converter logic.
The current culture.
The previous code sample shows the DateTime example mentioned before. In the Convert() method we get the original value and, after we’ve converted it into a DateTime object, we return a string with the short formatting.
In the ConvertBack() method, we get the string returned from the control and convert it into a DateTime object before sending it back to the code.
Converters are treated like resources—you need to declare them and include them in your binding expression using the StaticResource keyword.
It’s important to highlight that converters can have a negative impact on performance if you use them too heavily, since the binding operation needs to be reapplied every time the data changes. In this case, it’s better to find a way to directly modify the source data or to add a new property in your class with the modified value.
Controls
The Windows Phone 8 SDK includes many built-in controls that can be used to define the user interface of the application. There are so many controls that it’s almost impossible to analyze all of them in this series, so we’ll take a closer look at just the most important ones.
Layout Controls
Some controls simply act as containers for other controls and define the layout of the page. Let’s discuss the most important ones.
StackPanel
The StackPanel control can be used to simply align the nested controls one below the other. It is able to automatically adapt to the size of the child controls.
You can also use the StackPanel control to align controls horizontally, one next to the other, by setting the Orientation property to Horizontal.
Grid
The Grid control can be used to create table layouts, which fill the entire parent container’s size. It supports rows and columns in which you can place the different controls. The following code sample demonstrates its use:
You define the grid layout by using the RowDefinitions and ColumnDefinitions properties. You can add a RowDefinition tag for every row that the table will have, while the ColumnDefinition tag can be used to set the number of columns. For every row and column you can set the width and height, or you can simply omit them so that they automatically adapt to the nested controls.
To define a control’s position inside the grid, we’re going to use two attached properties, which are special dependency properties that are inherited from the Grid control and can be used with every control. With the Grid.Row property, we can set the row’s number, and with Grid.Column, we can set the column’s number.
The previous sample code is used to display a TextBlock in the cell that is placed in the first row, second column of the grid, as you can see in the following figure:
ScrollViewer
The ScrollViewer control is a container, but it doesn’t define a layout. If you want to arrange nested controls, you still have to use another container like a StackPanel or a Grid. The purpose of this control is to create a layout that is bigger than the size of the screen. This way, users will be able to scroll down to see the rest of the user interface.
This control is useful, for example, when you have to display text that doesn’t fit the size of the page.
Border
The Border control’s purpose is to display a border. This is useful because it’s able to contain a child control that will be wrapped into the border.
The following sample shows how to wrap an image inside a red border:
There are some key properties of the Border control. The first one is BorderThickness, which specifies the border’s thickness. You can specify a single value, as we did in the previous sample. In this case, the same thickness is applied to every side. You can also specify multiple values to give every border a different size, as in the following sample:
The second important property is BorderBrush, which is used to set the brush that is applied to the border. It can use any of the available XAML brushes. By default, it accepts a SolidColorBrush, so you can simply specify the color you want to apply.
Another useful property is Padding, which can be used to specify the distance between the border and the child control, as shown in the following sample:
Output Controls
The purpose of these controls is to display something to users, such as text, an image, etc.
TextBlock
TextBlock is one of the basic XAML controls and is used to display text on the screen. Its most important property is Text, which, of course, contains the text to display. You have many properties to choose from to modify the text’s appearance, such as FontSize, FontWeight, and FontStyle, and you can automatically wrap the text in multiple lines in case the text is too long by setting the TextWrapping property to true.
You can also apply different formatting to the text without using multiple TextBlock controls by using the Run tag, which can be used to split the text as shown in the following sample:
RichTextBlock
The RichTextBlock control is similar to TextBlock, but it offers more control over the formatting styles that can be applied to the text. Like the one offered by HTML, you can define paragraphs, apply different text styles, and more.
Image
The Image control can be used to display images. You can set the Source property with a remote path (an image’s URL published on the Internet) or a local path (a file that is part of your Visual Studio project). You can’t assign a path that refers to an image stored in the local storage of the application. We’ll see later in this series how to manage this limitation.
You can also control how the image will be adapted to fill the control’s size by using the Stretch property, which can have the following values:
Uniform: The default value. The image is resized to fit the container while keeping the original aspect ratio so that the image won’t look distorted. If the container’s aspect ratio is different from the image’s, the image will look smaller than the available space.
Fill: The image is resized to fit the container, ignoring the aspect ratio. It will fill all the available space, but if the control’s size doesn’t have the same aspect ratio as the image, it will look distorted.
UniformToFill is a mix of the previous values. If the image has a different aspect ratio than the container, the image is clipped so that it can keep the correct aspect ratio and, at the same time, fill all the available space.
None: The image is displayed in its original size.
Input Controls
These controls are used to get input from users.
TextBox
TextBox is another basic XAML control, and it’s simply a way to collect text from users. The entered text will be stored in the Text property of the control. When users tap a TextBox control, the virtual keyboard is automatically opened. As a developer, you can control the keyboard’s type that is displayed according to the data types you’re collecting.
For example, you can display a numeric keyboard if users only need to input a number; or you can use an email keyboard (which provides easy access to symbols like @) if you’re collecting an email address.
You can control the keyboard’s type with the InputScope property. The list of supported values is very long and can be found in the MSDN documentation. Some of the most used are:
Text for generic text input with dictionary support.
Number for generic number input.
TelephoneNumber for specific phone number input (it’s the same keyboard that is displayed when you compose a number in the native Phone application).
EmailNameOrAddress which adds quick access to symbols like @.
Url which adds quick access to common domains like .com or .it (depending on the keyboard’s language).
Search which provides automatic suggestions.
Tip: If the TextBox control is used to collect generic text, always remember to set the InputScope property to Text. This way, users will get support from the autocomplete and autocorrection tools.
PasswordBox
PasswordBox works exactly like the TextBox control, except that the inserted characters are automatically converted into dots so that people near the user won’t be able to read the text. As the name of the control implies, it’s typically used to collect passwords.
Theme Resources
One of a developer’s goals should be to keep the user interface of her or his application as consistent as possible with the guidelines provided by the operating system. To help achieve this goal, the SDK offers many out-of-the-box resources that can be applied to controls to get the same look and feel of the native applications. These styles are typically used with controls like TextBox, TextBlock, or RadioButton, and they provide a standard set of visual features (like font size, color, opacity, etc.) that are consistent with the other applications.
Another good reason to use theme resources is that they are aware of the theme set by users. For example, you can use the PhoneAccentBrush style if you want to give a control the same color as the phone’s accent color.
The many theme resources are split into different categories like brush resources, color resources, font names and styles, and text resources. You can find a complete list of the available styles in the MSDN documentation. They are simply applied using the Style property offered by every control, as shown in the following sample:
Interacting With Users
In this category, we can collect all the controls that we can use to interact with users, like Button, CheckBox, or RadioButton.
The text to display is set with the Content property, like in the following sample:
The Content property can also be complex so that you can add other XAML controls. In the following sample we can see how to insert an image inside a button:
These controls offer many ways to interact with users. The most common events are Click, Tap, and DoubleTap.
Note: Click and Tap are the same event—they are both triggered when users press the control. Tap has been introduced in Windows Phone 7.5 to be more consistent with the touch interface, but to avoid breaking old apps, the Click event is still supported.
The Windows Phone Signature Controls
Most of the controls we’ve seen so far are part of the XAML framework and are available on every other XAML-based technology, like Silverlight, WPF, and Windows Store apps.
However, there are some controls that are available only on the Windows Phone platform, since they are specific for the mobile experience. Let’s take a look at them.
Panorama
The Panorama control is often used in Windows Phone applications since it’s usually treated as a starting point. The control gets its name because an oversized image is used as the background of the page. Users are able to swipe to the left or to the right to see the other available pages. Since the image is bigger than the size of the page, the phone applies a parallax effect that is visually pleasing for users.
The other main feature of the Panorama control is that users can get a sneak peek of the next page. The current page doesn’t occupy all of the available space because a glimpse of the next page is displayed on the right edge.
A Panorama control is typically used to provide an overview of the content that is available in an application. It’s a starting point, not a data container. For example, it’s not appropriate to use a panorama page to display all the news published on a blog. It’s better, instead, to display only the latest news items and provide a button to redirect users to another page, where they will be able to see all of them.
From a developer’s point of view, a Panorama control is composed of different pages: each one is a PanoramaItem control that contains the layout of the page.
The Panorama can have a generic title, like the application’s title (which is assigned to the Title property), while every page can have its own specific title (which is assigned to the Header property).
Note: The Panorama control (like the Pivot control) is not available by default in a page. You’ll have to declare the following namespace:
Pivot
The Pivot control, from a technical and user interaction perspective, works in a similar way to the Panorama control—users can swipe the screen left or right to view the other pages. The difference, from the users’ point of view, is that the view will fit the screen’s size. Users can see which page is next because its header is displayed next to the current page’s header in gray.
However, the Pivot control is used for purposes not shared by the Panorama control:
To display one kind of information applied to different contexts. The previous figure is a good example. The information on each page is the same (the weather forecast), but referred to in different contexts (the cities).
To display different kinds of information that refer to the same context. A contact’s details page in the People Hub on a Windows Phone is a good example of this—you have much information (the contact’s details, social network updates, conversations, etc.), but it all belongs to the same context (the contact).
As previously anticipated, the XAML for the Pivot control works like the XAML for the Panorama control. The main control is called Pivot, while the nested controls that represent the pages are called PivotItem.
The ApplicationBar
The ApplicationBar is a control placed at the bottom of the page and is used as a quick access for functions that are connected to the current view.
You can add two element types to an application bar:
Icons are always displayed (unless the ApplicationBar is minimized), and up to four can be displayed at once.
Menu items are simply text items that are displayed only when the application bar is opened. There’s no limit to the number of items that can be included.
The ApplicationBar does not behave like the other XAML controls. It is not part of the page—in fact, it’s declared outside the main Grid, the one called LayoutRoot—and it doesn’t inherit from the FrameworkElement class, like every other control. The biggest downside of this is that the control doesn’t support binding; you’ll have to rely on third-party libraries, like the implementation available in the Cimbalino Toolkit for Windows Phone.
Here is an ApplicationBar sample:
ApplicationBar is a property of the PhoneApplicationPage class, which contains the real ApplicationBar definition. It’s not part of the standard XAML namespaces, but it’s part of the following namespace, which should already be declared in every standard Windows Phone page:
Icon buttons are declared directly inside the ApplicationBar tag. The base class is ApplicationBarIconButton, and the most important properties are Text (the icon description) and IconUri (the path of the image used as the icon), while Click is the event handler that is invoked when a user taps the button.
Menu items, instead, are grouped inside a property of the ApplicationBar control called MenuItems. You can add as many ApplicationBarMenuItem controls as you want. They behave like the button icons except that, since they’re just text, the IconUri property is missing.
Another important limitation of the ApplicationBar control is that we’re not able to assign the x:Name property to an ApplicationBarIconButton or ApplicationBarMenuItem control. This means that if we need to change a property’s value in the code behind, we can’t simply use the notation ControlName.PropertyName.
The work-around is to use the code behind to directly access the collections that contain the buttons and menu items that are available because of the ApplicationBar object. They are called Buttons and MenuItems, as you can see in the following code sample:
The purpose of this sample is to get access to the first icon button and first menu item inside the ApplicationBar, and to change the value of the Text property.
In the end, there are two other ways to customize the ApplicationBar. The first is to minimize it. This way, only the three dots at the right margin will be displayed; icons won’t be visible. To achieve this, you have to set the Mode property to Minimized.
The other way is to change the opacity. You can set the Opacity property with a value between 0 (transparent) and 1 (opaque). The biggest difference is that when ApplicationBar is translucent, the page content will go below the bar and fit the entire size of the screen; when the bar is opaque, the content won’t fit all of the available screen space since the bottom of the page will be reserved for the ApplicationBar.
Displaying Collections of Data With the LongListSelector
One of the most common requirements in an application is to display a collection of items which can be retrieved from a remote service or a local database. The Windows Phone SDK has included, since the beginning, some controls for this purpose, like ItemsControl and ListBox. In Windows Phone 8, Microsoft has introduced a new and more powerful control, which previously was available as part of the Windows Phone Toolkit (you’ll find more details about this toolkit later in this article). This control is called LongListSelector and has many advantages over other similar controls:
better performance
virtualization support to avoid loading all the data at the same time, instead loading data only when it is needed
group support to turn the list into a jump list, so that data is grouped in categories and users can easily jump from one to another (for example, in the People Hub, contacts are grouped by the first letter)
Creating a Flat List
The LongListSelector control can be used like a regular ListBox to display a flat list of items, without grouping. In this case, you just need to set the IsGroupingEnabled property to false. Except for this modification, you’ll be able to use a LongListSelector like a standard ItemsControl. You’ll define the ItemTemplate property with a DataTemplate to define the item layout, and you’ll assign the collection you want to display to the ItemsSource property.
Creating a List Grouped by Letter
Creating a list grouped by the first letter of the items is a bit more complicated since we have to change our data source. It won’t be a flat collection of data anymore. In addition, if we want to keep the user experience consistent with other applications, we’ll need to create a jump list with all the letters of the alphabet. The groups that don’t have any members will be disabled so that users can’t tap them.
To achieve this result, Microsoft offers a class called AlphaKeyGroup<T>, which represents a letter of the alphabet and all the items that start with it. However, this class is not part of the Windows Phone SDK, and should be manually added to your project by right-clicking on your project in the Solution Explorer in Visual Studio, and choosing Add new class. The following code example is the full implementation.
The main features of this class are:
It inherits from List<T>, so it represents a list of elements.
It has a property called Key, which is the key that identifies the group (the letter of the alphabet).
It uses a special collection type called SortedLocaleGroup, which is able to manage the cultural differences between one language and another.
It offers a method called CreateGroups(), which is the one we’re going to use to group our data.
To better explain how to use the AlphaKeyGroup<T> class, let’s use a real example. Let’s define a collection of people that we want to group by the first letters of their names, in a similar way the People Hub does. The first step is to create a class that represents a single person:
Then, when the application starts, we populate the list with a set of fake data, as shown in the following sample:
void LongListSelectorAlphabetic_Loaded(object sender, RoutedEventArgs e)
{