Category Archives: XAML101

XAML 101: Image Resizing with DecodePixelWidth and DecodePixelHeight

FacebookTwitterGoogle+Share

Source code for this sample on GitHub: https://github.com/billreiss/xamlnative/tree/master/Xaml101/009_DecodeImageWidthHeight

UPDATED: I missed an important detail in this sample, like I mention below I am learning about this topic myself. Hugo Vermaak pointed out that the image after using this technique lost some definition, and so I did a little more research and so added a section to the bottom of this post about DecodePixelType.

One of the reasons I love sharing knowledge with others is that it’s also a great learning experience. One of the best ways to learn about a technology is to decide to do a presentation on it, and then panic and cram and regret agreeing to doing it, and then finally pulling it all together and learning how it works in depth (well at least enough depth to be a convincing “expert”). Doing this blog series on XAML, I will learn a lot of new things along the way, and this is one of the first. After my previous post about Image and ImageBrush, Tim Heuer of Microsoft tweeted me:

So here we go, something new for me but it looks pretty cool. In the last sample, the original image was larger than the avatar we actually wanted to display. The original image was 300×300 but we were displaying it as 70×70. Here is the XAML we were using:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Ellipse Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" Width="70" Height="70">
        <Ellipse.Fill>
            <ImageBrush ImageSource="Images/healy.jpg" />
        </Ellipse.Fill>
    </Ellipse>
</Grid>

And the resulting app:

image

Looking at the above XAML, the image is loaded at its original resolution and then the image is scaled down by the Universal Windows Platform framework to the desired size. This can cause performance issues and also may not look great. There is a better way. If you know what size you want an image to be when you display it, and if it’s a JPEG or PNG file (the two most popular image formats on the web) you can have the image scale itself as it’s being loaded. The XAML is a little more complex but not too bad:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Ellipse Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" Width="70" Height="70">
        <Ellipse.Fill>
            <ImageBrush>
                <ImageBrush.ImageSource>
                    <BitmapImage UriSource="Images/healy.jpg" DecodePixelHeight="70" DecodePixelWidth="70" DecodePixelType="Logical"/>
                </ImageBrush.ImageSource>
            </ImageBrush>
        </Ellipse.Fill>
    </Ellipse>
</Grid>

Instead of specifying a path on the ImageBrush.ImageSource property, we tell the ImageBrush to use a BitmapImage as its ImageSource, and the BitmapImage has the DecodePixelHeight and DecodePixelWidth properties to tell the image decoder what size you want the image to be.

UPDATED: Notice the DecodePixelType property. This defaults to “Physical”, meaning that the image would be decoded to exactly 70×70 pixels. XAML uses device independent pixels (DIPs) which may or may not correspond to a single physical pixel. This depends on screen size and resolution in order to scale your app to look good on all devices. By setting DecodePixelType to Logical, the Windows 10 runtime will take that 70 pixels value and figure out how many actual pixels this is on the particular device, and decode at that size instead. It’s the best of both worlds, you get to decode to the exact size you actually need without doing all the calculations yourself.

Here is the app now:

image

You may not be able to tell a difference, I think it looks a little less “jaggy”. You can use the same technique on the Image’s Source property. You actually don’t need to specify DecodePixelHeight if you want to preserve the original aspect ratio, you can just give a value for DecodePixelWidth and the DecodePixelHeight will be calculated for you.

XAML 101: Image and ImageBrush

Source code for this sample on GitHub: https://github.com/billreiss/xamlnative/tree/master/Xaml101/008_Images

Images are very important to many Windows apps. It could be a user’s avatar, a photo app, or just a way to add some visual appeal, or a hundred other things. There are several ways to add an image, we’ll look at two of them here.

First let’s look at the Image control. We need an image to display, and this can come from the internet, can be packaged with your app, or can come from some other source. First let’s look at an internet-based image. Let’s make the MainPage.xaml Grid look like this:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Image Source="http://xamlnative.com/wp-content/uploads/2015/09/healy.jpg"/>
</Grid>

This is a photo of my good friend and Microsoft Evangelist Joe Healy. Check out his blog at http://devfish.net. Let’s run the app like this and see how it looks:

image

Notice how the image fills the available space but is centered preserving the aspect ratio. This is controlled by the Stretch property, and defaults to Uniform. There are a few other options for this, we can change it to Fill:

<Image Source="http://xamlnative.com/wp-content/uploads/2015/09/healy.jpg" Stretch="Fill"/>

image

Now it fills available space without preserving the aspect ratio. There is also UniformToFill which fills the entire space and preserves aspect ratio but any extra is cut off. There is also “None”, which centers the image in the available space but doesn’t scale it at all.

So far the image takes up all the available space, but what if we want to show it as an avatar next to a tweet or something similar. We would then want to specify its size and have it fit that size.

For this let’s change the alignment of the Image to Left and Top, and set the width and height explicitly:

<Image Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" Width="70" Height="70" Source="http://xamlnative.com/wp-content/uploads/2015/09/healy.jpg" Stretch="UniformToFill"/>

Now we get something like this:

image

Thus far we’ve been accessing an internet resource for the image, but let’s say you want to make it available offline. One way to do this is to package it with your app. Let’s add a new folder to the project called Images, and then add an Existing Item to that new folder. In my case that is a local copy of healy.jpg.

image

Then in the Image control definition, I can change the Source property to not use a url, and instead use a relative path:

<Image Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" Width="70" Height="70" Source="Images/healy.jpg" Stretch="UniformToFill"/>

Run the app again and you should see the same result as before.

This looks like an avatar you would see in an app, but Microsoft has decided in their design language that people should be represented as circles. When we want an Image that’s not rectangular, we can use an ImageBrush. Let’s also introduce another control, the Ellipse.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Ellipse Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" Width="70" Height="70">
        <Ellipse.Fill>
            <ImageBrush ImageSource="Images/healy.jpg" />
        </Ellipse.Fill>
    </Ellipse>
</Grid>

So we have an ellipse the same size as the previous Image, and with the same properties for alignment and margin. The Ellipse has a Fill property which is similar to the Grid’s Background property. Here we specify an ImageBrush with an ImageSource where the ImageSource has the same value of our earlier Image control’s Source property. The ImageBrush also has the same Fill property options as the Image control. Here is the result:

image

That’s enough of Image and ImageBrush for now, we will see these again in later posts.

XAML 101: The LinearGradientBrush

Source code for this sample on GitHub: https://github.com/billreiss/xamlnative/tree/master/Xaml101/007_LinearGradientBrush

We will pick up where the last post left off where we had a red SolidColorBrush on the Grid for MainPage.xaml:

<Grid>
    <Grid.Background>
        <SolidColorBrush Color="Red"/>
    </Grid.Background>
</Grid>

There are other default Brushes available, and this post focuses on the LinearGradientBrush. What this Brush does is let you specify a sequence of colors that will be used to create a color gradient pattern.

NOTE: There is a RadialGradientBrush for creating a circular or elliptical gradient that was available in Silverlight and WPF, but it is not currently supported in UWP apps so we won’t cover it at this point. If you want RadialGradientBrush added to Windows 10 Universal Apps vote for it here: http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/5890481-please-add-the-radialgradientbrush-to-windows-stor

Let’s change the Background to use a LinearGradientBrush:

<Grid>
    <Grid.Background>
        <LinearGradientBrush>
            <GradientStop Offset="0" Color="Red"/>
            <GradientStop Offset="1" Color="Blue"/>
        </LinearGradientBrush>
    </Grid.Background>
</Grid>

The first thing you will probably notice is the GradientStop elements. These values go from 0 to 1, and you can specify any value in between. We will see that soon. The result looks like this:

image

By default, the gradient goes from the upper left corner to the lower left corner. We can change this by modifying the StartPoint and EndPoint poprerties:

<Grid>
    <Grid.Background>
        <LinearGradientBrush StartPoint=".5,0" EndPoint=".5,1">
            <GradientStop Offset="0" Color="Red"/>
            <GradientStop Offset="1" Color="Blue"/>
        </LinearGradientBrush>
    </Grid.Background>
</Grid>

And the result is like this:

image

Here we changed the start point and end point so that the X value is .5, and the Y value goes from 0 to 1. The default is a start point of 0,0 and and end point of 1,1. We can do a gradient along the X axis like this:

<Grid.Background>
    <LinearGradientBrush StartPoint="0,.5" EndPoint="1,.5">
        <GradientStop Offset="0" Color="Red"/>
        <GradientStop Offset="1" Color="Blue"/>
    </LinearGradientBrush>
</Grid.Background>

image

You can have any number of gradient stops, let’s add another:

<Grid.Background>
    <LinearGradientBrush StartPoint="0,.5" EndPoint="1,.5">
        <GradientStop Offset="0" Color="Red"/>
        <GradientStop Offset=".5" Color="Yellow"/>
        <GradientStop Offset="1" Color="Blue"/>
    </LinearGradientBrush>
</Grid.Background>

image

The colors blend from one to the other between the gradient stops, but let’s say you wanted a sharp transition. We can do something like this:

<Grid.Background>
     <LinearGradientBrush StartPoint="0,.5" EndPoint="1,.5">
         <GradientStop Offset="0" Color="Orange"/>
         <GradientStop Offset=".5" Color="Red"/>
         <GradientStop Offset=".5" Color="Yellow"/>
         <GradientStop Offset="1" Color="Blue"/>
     </LinearGradientBrush>
 </Grid.Background>

By having 2 gradient stops at the same offset, the transition between those 2 colors is immediate and gives us a sharp change in color:

image

So far the StartPoint and the EndPoint have encompassed the entire surface. What if we change the EndPoint to halfway?

<LinearGradientBrush StartPoint="0,.5" EndPoint=".5,.5">
    <GradientStop Offset="0" Color="Orange"/>
    <GradientStop Offset=".5" Color="Red"/>
    <GradientStop Offset=".5" Color="Yellow"/>
    <GradientStop Offset="1" Color="Blue"/>
</LinearGradientBrush>

And this is the result:

image

There is another property on the LinearGradientBrush called SpreadMethod which determines what happens in the parts of the surface that the brush doesn’t cover. This deafaults to “Pad”, where the extra area is filled with whatever the last color was. There are a couple of other options, one is Reflect:

<LinearGradientBrush StartPoint="0,.5" EndPoint=".5,.5" SpreadMethod="Reflect">

image

Pretty cool. The other is Repeat:

<LinearGradientBrush StartPoint="0,.5" EndPoint=".5,.5" SpreadMethod="Repeat">

image

A long post, but there are a lot of options with this Brush. Be creative and try your own combinations.

XAML 101: Colors and SolidColorBrush

Source code for this sample on GitHub: https://github.com/billreiss/xamlnative/tree/master/Xaml101/006_SolidColorBrush

Create a new “Universal Blank App” project, or use the HelloXaml project we created earlier. In MainPage.xaml, change the Grid to look like this:

<Grid Background="Red">
</Grid>

When we run this, we just get a red background for the page:

image

Looks pretty simple, but there is a bit more going on behind the scenes, and the UWP framework does some things for us to help out. First of all, Red is a predefined color. There are many of these, and it can be easier and more descriptive than specifying a hex value. That being said, this is equivalent to what’s above:

<Grid Background="#FFFF0000">
</Grid>

The first “FF” is the transparency value, and a value of “FF” is fully opaque. The the other pairs are red, green, and blue respectively. So we have full red, and no green or blue. The transparency value is optional if you want no transparency, so this is also equivalent:

<Grid Background="#FF0000">
</Grid>

 

Now if you look at the definition of the Grid.Background property, it looks like this:

image

So we see that Background is of type Brush, and not Color. Most places in XAML that take a color (backgrounds, border colors, foregrounds) are of type Brush. When a color is specified for Background, like Red, this value is converted automatically to a SolidColorBrush for you, so that you don’t have to use the longer form of specifying a SolidColorBrush of type Red, but we can do that:

<Grid>
    <Grid.Background>
        <SolidColorBrush Color="Red"/>
    </Grid.Background>
</Grid>

And this is exactly the same when it is drawn.

There are some more interesting brushes available and in the next post we will look at another of these, the LinearGradientBrush.

XAML 101: Borders, Margins, and Alignment

Source code for this sample on GitHub: https://github.com/billreiss/xamlnative/tree/master/Xaml101/005_Borders_Margins_Alignment

In this post we will look at another control, and some other properties that can help us with layout. The new control for this post is the Border, and it is similar to the Grid, but it only has a single child and no rows or columns. You can think of it as a frame for another control.

Let’s modify the Grid in MainPage.xaml to look like this:

<Grid Background="Red">
    <Border Background="Cyan">
        <TextBlock Text="Border Content"/>
    </Border>
</Grid>

We have a Border with a TextBlock inside it. Running the app looks like this:

image

Notice that the Border fills the entire Grid (we don’t see any of the Red background of the Grid). This is because the HorizontalAlignment and VerticalAlignment properties default to “Stretch” to fit the container.  Changing the Border’s alignments:

<Border HorizontalAlignment="Left" VerticalAlignment="Top" Background="Cyan">
    <TextBlock Text="Border Content"/>
</Border>

Now the Border is in the upper left corner:

image

It’s really hugging the edge there. We can give it some space using the Margin property:

<Border Margin="10,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top" Background="Cyan">

And now it looks like this:

image

The Border’s Margin is set to “10,10,10,10”. These numbers represent the Left, Top, Right, and Bottom margins respectively. Note that this is a different order than margins in HTML where the order is Top, Right, Bottom, Left. We can also represent Margin as two numbers or a single number. In the case of two numbers, the Left and Right are set to the first number specified, and the Top and Bottom to the second number. If only one number is specified then all margins are set to this value. So we can change the Margin we specified above to this:

<Border Margin="10" HorizontalAlignment="Left" VerticalAlignment="Top" Background="Cyan">

If we move the Margin to the TextBlock instead of the Border, we get a slightly different look:

image

Now the background of the Border goes all the way to the edge, but the text is in the same position it was when the Margin was on the Border. There is another way to achieve this same result. We can set the Padding property on the Border:

<Border Padding="10" HorizontalAlignment="Left" VerticalAlignment="Top" Background="Cyan">

Padding is available only on some controls, where Margin is available everywhere. With Padding, it has the same effect as putting a Margin around the content contained within the Border.

Let’s consider one more type of alignment, and that is text alignment. Let’s let the Border stretch to fill the control again, and set the TextAlignment property of the TextBlock:

<Border Padding="10" Background="Cyan">
    <TextBlock TextAlignment="Center" Text="Border Content"/>
</Border>

And we get something that looks like this:

image

Now we can get a very similar effect by setting the Border or the TextBlock to HorizontalAlignment=”Center” but there is a subtle but important difference. What happens when text is too big to fit in the available space horizontally? Change the Border and TextBlock to this:

<Border Padding="10" Background="Cyan">
    <TextBlock Text="This is a very long piece of text that won't fit on the page. Are you still reading this?"/>
</Border>

Running this and shrinking down the window as small as it will go, it looks like this:

image

Notice how the text gets cut off. That’s because text wrapping on the TextBlock is off by default. We can easily fix this:

<TextBlock TextWrapping="Wrap" Text="This is a very long piece of text that won't fit on the page. Are you still reading this?"/>

Now the app wraps the text:

image

No matter how we try, and whatever HorizontalAlignments we use, the second line will always be left justified. However if we set TextAlignment to “Center” then both lines will be centered:

image

XAML 101: Grid Sizing

Source code for this sample on GitHub: https://github.com/billreiss/xamlnative/tree/master/Xaml101/004_GridSizing

In the last post we looked at Dependency Properties and a special version of those called Attached Properties. Some of the importance of these will become clearer later, but for now just treat them like you would any other property. Let’s see what other properties we can use on the powerful and flexible Grid control and its children for positioning.

In our “Hello World” app, in MainPage.xaml, we had a Grid with a couple of RowDefinitions and two TextBlocks. Let’s change things up a little to make it easier to see what is going on. Change the MainPage.xaml Grid to look like this:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid Background="Yellow">
            <TextBlock Text="Row 0"/>
        </Grid>
        <Grid Grid.Row="1" Background="LightBlue">
            <TextBlock Text="Row 1"/>
        </Grid>
        <Grid Grid.Row="2" Background="Orange">
            <TextBlock Text="Row 2"/>
        </Grid>
        <Grid Grid.Row="3" Background="Green">
            <TextBlock Text="Row 3"/>
        </Grid>
    </Grid>

Now our Grid has 4 nested Grids inside it, and each one is in a different row, and each has a TextBlock inside it. We can nest as many Grids and other controls inside each other as we want to get the layout we desire. By setting the Background property on each of these it is easy to see the space they take up. It looks like this:
image

So we can see that these rows each take up one quarter of the available space on the page. There are 3 different types of sizing for rows (and columns) in a grid. The default is “Star” sizing, which is what we see here. A little more about that later in this post. The next sizing type is “Auto” and we can see what this does by changing the Grid.RowDefinitions as follows:

<Grid.RowDefinitions>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

And this is what it looks like in the running app:

image

The “Auto” size for rows sizes the row to the size of the largest element in that row. The same is true for Grid columns. Since we only have one element in each row, each row is sized to fit its content. The third type of sizing is “Pixel” sizing. Let’s change the row definitions like this:

<Grid.RowDefinitions>
    <RowDefinition Height="70"/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

Now the first row will be 70 pixels high, and the other rows will size to fit their contents, like this:

image

Now back to “Star” sizing. The name “Star” comes from the asterisk that is used to show that we want to use Star sizing. The following are all equivalent:

<RowDefinition/>
<RowDefinition Height="*"/>
<RowDefinition Height="1*"/>

The default height for a row definition is “1*”, and  the “1” is implied if not specified. The number before the Star determines how much of the available space will be reserved for the row. These numbers are only important in relation to each other, if you have more than one “Star sized” row in your Grid. How it works is that “Pixel sized” and “Auto sized” are given space first, and then the remaining space is split between the “Star sized” rows. All of the numbers for “Star sized” rows are added up, and then each is given a percentage based on its value. By combining star sizes with fixed sizes (auto or pixel) you can easily create some advanced layouts such as master-detail views. Let’s see how this works. Modify the Grid.RowDefinitions as follows:

<Grid.RowDefinitions>
    <RowDefinition Height="70"/>
    <RowDefinition Height="1*"/>
    <RowDefinition Height="1*"/>
    <RowDefinition Height="2*"/>
</Grid.RowDefinitions>

And the resulting app looks like this:

image

The first row gets 70 pixels, then the next 2 rows each get 25 percent of the remaining space, and the final row gets 50 percent of the remaining space. If you prefer percentages, you can do something like this with the same result:

<Grid.RowDefinitions>
    <RowDefinition Height="70"/>
    <RowDefinition Height=".25*"/>
    <RowDefinition Height=".25*"/>
    <RowDefinition Height=".50*"/>
</Grid.RowDefinitions>

That’s it for Grid sizing basics, remember that all of these same concepts apply to Grid.ColumnDefinitions except using the Width property instead of the Height.

XAML 101: Dependency Properties and Attached Properties

Source code for this sample on GitHub: https://github.com/billreiss/xamlnative/tree/master/Xaml101/003_Dependency_Attached_Properties

This is one of those topics where it’s pretty advanced, but it’s also so fundamental to the technology that it needs to be addressed. So what we will do is talk about these Properties as they are implemented by other controls, and later we will look at how we can create our own Properties. In the last post, we set the Text property of the TextBlock. This Text property, and pretty much every other property you set on a control is actually a Dependency Property. In C#, when you create a property it’s usually something like this:

        public string Text { get; set; }

In UWP and other XAML based technologies, properties that you need to be able to access in XAML are a bit more complex. There are things like animations, data binding, triggers, setters, and more and these require notifications when the value of a property is changed. Most properties on controls are implemented as Dependency Properties. These are properties that are registered, and their values are accessed via GetValue and SetValue methods. Generally they also have simple property wrappers around these methods so that you can access them as easily as any other property. A lot more about the details of how to implement these later.

The reason I think this is important to bring up now is that there is a type of Dependency Property that is called an Attached Property. Dependency Properties are declared on a class and then are attached to another class. Dependency Properties like the TextBlock.Text property are declared on the same class that they are attached to. If a Property is declared against one class, but is attached to a different class, then this is called an Attached Property. Yes I understand that this is a little confusing, and I think an example can help. Let’s start with the HelloXaml sample from the last post. In MainPage.xaml we had this:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="Hello XAML!"/>
    </Grid>

Like I said earlier, the Text property of the TextBlock is a Dependency Property. The Background property of the Grid is too, we will talk about the strange syntax there soon. Dependency Properties in XAML can be set using XML attribute syntax (like Text and Background) but for more complex properties there is also an element syntax. Let’s consider defining two rows for our Grid control. There is a Dependency Property on Grid which is called RowDefinitions. This is how we can define two rows:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Text="Hello XAML!"/>
    </Grid>

Now let’s put something in the second row. This is done using the Grid.Row Attached Property.

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Text="Hello XAML!"/>
        <TextBlock Grid.Row="1" Text="Hello Second Row!"/>
    </Grid>

The first row is row 0, so the second row is row 1. Notice the Grid.Row attached property on the second TextBlock. The Row attached property is declared on the Grid but is attached to the row, and that’s why when we use this attached property we need to say Grid.Row instead of just Row. You can actually put this prefix on any dependency property, but it’s not required. For example, instead of:

Text="Hello Second Row!"

We could say:

TextBlock.Text="Hello Second Row!"

Run this again and you will see something like this:

image

Notice how the rows are spaced and the two rows take up the same amount of space on the page. There are some other properties that can control this and in the next post we will see some of these.

XAML 101: Our First App (Part 2)

Source code for this sample is at GitHub here: https://github.com/billreiss/xamlnative/tree/master/Xaml101/002_OurFirstApp_Part2

In the last post we created a new C# Universal Windows Platform (UWP) app, ran it, and took a look at what gets generated. We also disabled the frame rate counter. Now it’s time to really get in to the XAML part of the app. MainPage.xaml contains the layout for the home page of the app. Let’s take a look.

This is what gets generated in MainPage.xaml:

<Page
    x:Class="HelloXaml.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloXaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    </Grid>
</Page>

So the first thing to notice are these xmlns attributes. These are XML namespaces and this is how XAML finds what it needs. Generally these map to .NET namespaces and assemblies and you can think of it similar to the “using directive” in C# (for example “using System.Collections.Generic;”),  more about these later. The “x” namespace is a special one used by XAML for internal built-in extensions. We see “x:Class”, and this is used to declare the class name for this class. This will match the namespace in the code behind in the MainPage.xaml.cs file:

namespace HelloXaml
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
    }
}

So we have a code behind class of HelloXaml.MainPage, and we have a MainPage.xaml file with an x:Class of HelloXaml.MainPage. This links these two files together. Now a little about how the sausage is made. Even though you really don’t have to worry about this, I think it helps to know what is going on.

The MainPage.xaml file has a Build Action of “Page”. This tells Visual Studio to generate a partial class that is compiled along with MainPage.xaml.cs to create our HelloXaml.MainPage class. This generated file, named MainPage.g.i.cs has an InitializeComponent() method which is called from the MainPage constructor (see above). Any named entities (we will get to this later) will have generated code here, there is also code to load the XAML file into the object (known as deserializing or hydrating).

The root control inside the MainPage is a Grid control. You can change this if you want to, but the Grid is a pretty good choice for the root element in your page. A Grid has rows and columns (defaults to 1 row and 1 column) and you can think of it like a Table in HTML. Grid inherits from Panel, and there are a few other types that also inherit from Panel, and we will see these as we move on. The important thing about Panel (and Grid, since it inherits from Panel) is that it can have children. The various controls that inherit from Panel differ in how they treat the arrangement of their children.

Let’s add some text to the Grid. This is done with a TextBlock control. Inside the Grid, add a <TextBlock/> like this:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock/>
    </Grid>

Now with this selected, let’s look at the Properties pane of Visual Studio. I’m a big fan of the Properties pane, especially when we get to data binding later. I like to arrange the properties By Name, but that’s up to you, whatever you prefer. When arranged by name, we can scroll down and find the Text property. Let’s set it to “Hello XAML!”. You will see in the XAML window that this change has been applied there:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="Hello XAML!"/>
    </Grid>

Run the app again, it will look something like this:

image

XAML 101: Our First App

Source code for this sample is on GitHub here: https://github.com/billreiss/xamlnative/tree/master/Xaml101/001_OurFirstApp_Part1

Let’s do the obligatory “Hello World” app and use it to show what gets generated by Visual Studio out of the box when creating a Windows 10 Universal App. Before we get started, a few things you will need:

Now in Visual Studio, select File->New Project. Under Templates->Visual C#->Windows->Universal and select Blank App (Universal Windows) and call it HelloXaml. Click OK.

image

This creates a project structure that looks something like this:

image

Run the app. You should see a blank window like this:

image

There are a lot of supporting files in the project, such as icons, configuration information, and more, and we will dig into some of these later through the course of this series. The most important files for us right now that get generated are App.xaml, App.xaml.cs, MainPage.xaml, and MainPage.xaml.cs. Here is a brief description of each of these:

App.xaml – Contains application-wide resources such as styles. Putting control styles here can keep the look and feel of your app consistent across different pages. Not much here by default except whether the app should use the light or dark theme.

image

App.xaml.cs – This is run on startup, creates the default frame for all of your app’s pages, navigates to the first page. Also handles app suspend and resume.

MainPage.xaml – The layout of the home page of your app.

MainPage.xaml.cs – The code for the home page of your app.

If you run the app in the debugger, you will see something like this in the upper left corner:

image

This is a frame rate counter, and can be useful when troubleshooting performance problems, but generally it’s just annoying. We can get rid of it pretty easily. In App.xaml.cs, at the top of the OnLaunched method, you will see the following:

#if DEBUG
            if (System.Diagnostics.Debugger.IsAttached)
            {
                this.DebugSettings.EnableFrameRateCounter = true;
            }
#endif

Let’s change this to:

#if false
            if (System.Diagnostics.Debugger.IsAttached)
            {
                this.DebugSettings.EnableFrameRateCounter = true;
            }
#endif

This way it’s easy to turn it back on again if we need it, but until then it will stay out of our way. This is a good place to stop, in the next post we will start digging in to the actual XAML of the app.

XAML 101: What is XAML Anyway?

Welcome to the first in a series of posts introducing beginners to the world of developing Windows 10 Universal Windows Platform (UWP) apps using XAML. No previous knowledge will be assumed, but some working knowledge of C# will be very helpful. I try to keep my posts lighthearted and easily accessible, we will see how I do.

XAML (or Xaml, depending on your preference, I will try to be consistent and capitalize it) was originally introduced as part of Windows Presentation Foundation (WPF) and it is a general purpose XML based format for representing any .NET object, but it is overwhelmingly used for representing layout (similar to HTML for web apps). XAML stands for eXtensible Application Markup Language (or originally eXtensible Avalon Markup Language, the code name for WPF was Avalon back in the Windows Longhorn days).  If you develop an app using XAML for Windows 10, it is generally a combination of XAML for layout and C# (or C++ or VB.NET) code for application logic. Most things you can do in XAML can also be done in code, but XAML lends itself well to design tools which can increase productivity.

XAML has come a long way in Windows 10, and a lot of the built in user interfaces in Windows 10 including the start menu, action center, settings window, Edge browser, and much more all use XAML. The Office Universal apps also use XAML. These teams are so demanding about CPU and memory performance, and the UWP SDK team had to make a lot of improvements to make their platform acceptable. We as Windows 10 app developers benefit from all these improvements and I will cover these topics as we progress through learning about XAML for Windows 10 apps.

In the next post we will create the obligatory “Hello XAML” app and start learning about this powerful app platform.