XAML 101: Getting Started with Data Binding

FacebookTwitterGoogle+Share

Source code for this post on GitHub: https://github.com/billreiss/xamlnative/tree/master/Xaml101/015_DataBinding

Data binding is a huge topic in XAML, it’s pervasive and whether you are following the Model View ViewModel (MVVM) design pattern that’s very popular in XAML or  if you just want to populate a list of elements, you’ll probably need to use data binding in some form in your app. We will cover some now, and then there will probably be more topics as we progress.

Data binding has been around a long time. You could do it in Windows Forms apps. PowerShell and Delphi were built around it. I feel that with XAML they finally got it right, and it has made it to the point where if you’re not using it to build your app, you may be doing it wrong.

Data binding gives you a bridge between the data and the layout, and reduces the code you need to write to wire these two parts together. In earlier XAML based frameworks (WPF, Silverlight, WinRT for Windows 8) data binding was very dynamic and a lot was done at run time using reflection to make it work. Reflection is slow and memory intensive. When the Windows Shell team and the Office team started using XAML to develop Windows 10 apps and shell components, they ran into these performance and resource issues and came back to the Windows 10 Universal Windows Platform (UWP) team and asked for guidance. These teams are so focused on performance and will reject a technology if it doesn’t fit their needs. At first the UWP team considered guiding them to not use data binding and just wire up everything in code, which is what was typical in WinForms apps. Then they came up with a better way. More about it here. There is a new data binding system in Windows 10 UWP and it removes most of the old concerns about performance issues in traditional data binding in XAML. We won’t cover the old method of data binding, at least not yet, because I feel it’s best to lead in the recommended direction for best practices.

So what’s different about the new way? The heavy lifting is done at compile time. Code is generated to improve performance. No reflection is used. Binding errors are found at compile time. You can put breakpoints in the generated code. The defaults are set to maximize performance. Unless it doesn’t do what you need in some specific situation, I recommend using the new way. The new way is referred to as compiled bindings, or xBind.

Data bindings in general or xBind in particular are XAML markup extensions. We have seen some of these already, specifically ThemeResource and StaticResource. It’s a bit of a testament to XAML that Microsoft was able to swap out the data binding strategy.

NOTE: Compiled bindings are only currently available in Windows 10 UWP apps. I would love to see them in WPF too, if you agree go vote for it at http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/7810488-implement-x-bind-for-wpf. Microsoft really pays attention to this and you can make a difference.

In over 15 posts so far in the  XAML 101 series, I don’t think we have actually left XAML and written a line of C# code. There is only so much you can do in straight XAML and at some point the data needs to come from somewhere. Later we’ll dig into some design patterns and some suggestions on how to organize your code but data binding is useful without all of that.

Let’s look at a couple of very simple data binding examples, and then we can go from there in future posts. Consider these changes to the MainPage.xaml.cs file:

public sealed partial class MainPage : Page
{
    string FieldBindingText = "Here is a Field Binding";
    string PropertyBindingText
    {
        get; set;
    }

    public MainPage()
    {
        this.InitializeComponent();
        this.PropertyBindingText = "This is a Property Binding";
    }
}

We have two strings, one is a field and one is a property. Now in the MainPage.xaml we can do this:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel>
        <TextBlock Text="{x:Bind FieldBindingText}"/>
        <TextBlock Text="{x:Bind PropertyBindingText}"/>
    </StackPanel>
</Grid>

Notice the Text properties use the x:Bind markup extension, and the names match the string field and property we created in the code behind file. The compile bindings markup extension automatically looks to the current class definition for matching elements. running the app looks like this:

image

Let’s then change the first TextBlock to look like this:

<TextBlock Text="{x:Bind aFieldBindingText}"/>

Since the name specified no longer can find a match, we get a compile time error:

image

That’s it for now, stay tuned.

XAML 101: Resource Dictionaries

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

We have seen how to create our own resources, use built in resources and styles, and create styles of our own. This gives us a lot of power over the layout of our app, but all of these resource definitions can clutter our pages and/or the App.xaml file. You also might want to reuse your resource definitions on other pages or in other apps, and that his hard to do if you have these resources defined inline unless you just copy/paste everything. Fortunately there is a better way by using resource dictionaries.

A Resource Dictionary is a special type of XAML file that contains a set of resource definitions. Let’s add one to our project. First let’s create a new folder in the project called Resources. This isn’t required but I feel it’s good to organize a bit. Select this new folder then in the Project menu select Add New Item (you can also right click on the Resources folder and select it there):

image

Now you should see the types of new items you can create. One of them will be Resource Dictionary. We’ll call it MyResources.xaml.

image

This is what Visual Studio creates for us:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloXaml.Resources">
    
</ResourceDictionary>

Consider this XAML where we declare a Style in the Page Resources:

<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">
    <Page.Resources>
        <Style x:Key="TitleBlueStyle" BasedOn="{StaticResource TitleTextBlockStyle}" TargetType="TextBlock">
            <Setter Property="Foreground" Value="Blue"/>
        </Style>
    </Page.Resources>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel>
            <TextBlock Text="Here is some text" Style="{StaticResource TitleBlueStyle}"/>
            <TextBlock Text="Some more text"/>
            <TextBlock Text="3rd line of text"/>
        </StackPanel>
    </Grid>
</Page>

And this what the the app looks like when running:

image

We can move the Style definition to the MyResources.xaml file:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloXaml.Resources">
    <Style x:Key="TitleBlueStyle" BasedOn="{StaticResource TitleTextBlockStyle}" TargetType="TextBlock">
        <Setter Property="Foreground" Value="Blue"/>
    </Style>
</ResourceDictionary>

And then we can use this resource dictionary in our page:

<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">
    <Page.Resources>
        <ResourceDictionary Source="Resources/MyResources.xaml"/>
    </Page.Resources>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel>
            <TextBlock Text="Here is some text" Style="{StaticResource TitleBlueStyle}"/>
            <TextBlock Text="Some more text"/>
            <TextBlock Text="3rd line of text"/>
        </StackPanel>
    </Grid>
</Page>

And this will give us the same result. So this is great if we have one file with all our resource definitions in it, and then we can just reference it like this in each page, or we could reference it in the App.xaml file so the whole app can have access to these resources:

<Application
    x:Class="HelloXaml.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloXaml"
    RequestedTheme="Light">
    <Application.Resources>
        <ResourceDictionary Source="Resources/MyResources.xaml"/>
    </Application.Resources>
</Application>

But what if we have more than one resource dictionary to combine? This could happen if you have a fairly large app, and you want to keep your resources manageable. This can be done using the MergedDictionaries property like this:

<Application
    x:Class="HelloXaml.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloXaml"
    RequestedTheme="Light">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/MyResources.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

The MergedDictionaries property can take a list of ResourceDictionary entries so that you can break down your resources in any way that makes sense to your development process.

XAML 101: Built in Styles and “Cascading”

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

In the last post, we looked at how you can create your own styles and use those to provide a consistent look and feel to your application. There are also some styles that are provided for you that can give your app a consistent look with other Universal Windows Platform apps. Consider the following XAML:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel>
        <TextBlock Text="Here is some text"/>
        <TextBlock Text="Some more text"/>
        <TextBlock Text="3rd line of text"/>
    </StackPanel>
</Grid>

Select the first TextBlock, and in the Properties pane go to the Style property and click the “peg” next to it, and under System Resources select “TitleTextBlockStyle”. Your XAML should now look like this:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel>
        <TextBlock Text="Here is some text" Style="{StaticResource TitleTextBlockStyle}"/>
        <TextBlock Text="Some more text"/>
        <TextBlock Text="3rd line of text"/>
    </StackPanel>
</Grid>

And the app looks like this:

image

Notice that this is a StaticResource and not a ThemeResource. This is because it is not defined in the themed resources section of the built in resources files. We can take a look at the definition for this style by right clicking in the XAML on the TitleTextBlockStyle and then choose Go To Definition.

image

And here is the definition you will see:

<Style x:Key="TitleTextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
    <Setter Property="FontWeight" Value="SemiLight"/>
    <Setter Property="FontSize" Value="24"/>
    <Setter Property="OpticalMarginAlignment" Value="TrimSideBearings"/>
</Style>

It looks a lot like the one we created in the last post. There is however one extra thing here. See the BasedOn property on the Style object? This is how XAML does something similar to “cascading” in HTML and CSS, where one style is based on another. This allows you to create a base style, then create a new style based on that one, and adjusting the values of the properties you need. This is the definition of the BaseTextBlockStyle:

<Style x:Key="BaseTextBlockStyle" TargetType="TextBlock">
    <Setter Property="FontFamily" Value="Segoe UI"/>
    <Setter Property="FontWeight" Value="SemiBold"/>
    <Setter Property="FontSize" Value="15"/>
    <Setter Property="TextTrimming" Value="None"/>
    <Setter Property="TextWrapping" Value="Wrap"/>
    <Setter Property="LineStackingStrategy" Value="MaxHeight"/>
    <Setter Property="TextLineBounds" Value="Full"/>
</Style>

So the FontWeight and FontSize properties are overridden in the child style, but everything else will be inherited.

We can do the same thing, and base a Style on the built in TitleTextBlockStyle.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.Resources>
        <Style x:Key="TitleBlueStyle" TargetType="TextBlock" BasedOn="{StaticResource TitleTextBlockStyle}">
            <Setter Property="Foreground" Value="Blue"/>
        </Style>
    </Grid.Resources>
    <StackPanel>
        <TextBlock Text="Here is some text" Style="{StaticResource TitleBlueStyle}"/>
        <TextBlock Text="Some more text"/>
        <TextBlock Text="3rd line of text"/>
    </StackPanel>
</Grid>

Here we inherit from TitleTextBlockStyle and set the Foreground to Blue, and then use this new style on the TextBlock. This is how the app looks now:

image

XAML 101: Getting Started with Styles

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

So far we have seen ThemeResources and also created our own Resources that we can then use with the StaticResource markup extension. We can mix and match these to customize any element in our XAML.

Consider the XAML from the last post:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.Resources>
        <SolidColorBrush x:Key="redBrush" Color="Red"/>
    </Grid.Resources>
    <StackPanel>
        <TextBlock Text="Here is some text" Foreground="{StaticResource redBrush}"/>
        <TextBlock Text="Some more text" Foreground="{StaticResource redBrush}"/>
        <TextBlock Text="3rd line of text" Foreground="{StaticResource redBrush}"/>
    </StackPanel>
</Grid>

Let’s add the use of a built in themed resource to set the font size. Select the first TextBlock, and then in the Properties pane (I like to Arrange by Name, I think it’s easier to find things that way) look for the FontSize property. It should be showing a value of 15, the default font size for a TextBlock. Click the little “peg” next to it.

image

This brings up a menu with a few options. Pick System Resource then TextStyleExtraLargeFontSize. The XAML should now look like this:

<TextBlock Text="Here is some text" Foreground="{StaticResource redBrush}" FontSize="{ThemeResource TextStyleExtraLargeFontSize}"/>

You can copy and paste this FontSize property to the other TextBlocks, or set each the same way we set the first one.

Now we have some large red text.

image

Now it’s right up against the edge, so let’s add a Margin to each TextBlock:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.Resources>
            <SolidColorBrush x:Key="redBrush" Color="Red"/>
        </Grid.Resources>
        <StackPanel>
            <TextBlock Text="Here is some text" 
                       Margin="10,0,10,0" 
                       Foreground="{StaticResource redBrush}" 
                       FontSize="{ThemeResource TextStyleExtraLargeFontSize}"/>
            <TextBlock Text="Some more text" 
                       Margin="10,0,10,0" 
                       Foreground="{StaticResource redBrush}" 
                       FontSize="{ThemeResource TextStyleExtraLargeFontSize}"/>
            <TextBlock Text="3rd line of text" 
                       Margin="10,0,10,0" 
                       Foreground="{StaticResource redBrush}" 
                       FontSize="{ThemeResource TextStyleExtraLargeFontSize}"/>
        </StackPanel>
    </Grid>

Now it looks like this:

image

This is fine, and we are getting the results we want, but now we’re back to the fragility problem where we have to change things in multiple places if we want to change the design of the app. This is where Styles come in. You may be familiar with styles in HTML using CSS, and generally you can think about these the same way.

Styles in XAML allow you to specify values for multiple properties and apply them to a control. There are some other things you can do with styles too, and we will see those over time, but let’s get through the basics now.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.Resources>
        <SolidColorBrush x:Key="redBrush" Color="Red"/>
        <Style x:Key="redLargeTextStyle" TargetType="TextBlock">
            <Setter Property="Margin" Value="10,0,10,0"/>
            <Setter Property="Foreground" Value="{StaticResource redBrush}"/>
            <Setter Property="FontSize" Value="{ThemeResource TextStyleExtraLargeFontSize}"/>
        </Style>
    </Grid.Resources>
    <StackPanel>
        <TextBlock Text="Here is some text" Style="{StaticResource redLargeTextStyle}"/>
        <TextBlock Text="Some more text" Style="{StaticResource redLargeTextStyle}"/>
        <TextBlock Text="3rd line of text" Style="{StaticResource redLargeTextStyle}"/>
    </StackPanel>
</Grid>

This XAML defines a Resource of type Style, and gives it a key name so we can reference it where we want, and tells it what type of control this style applies to. The Style then contains a list of Setters with property names and values. We then set the Style property on each TextBlock to use the Style we defined as a Resource.

image

Things look just like they did before, but now if we want to change any of the property setter values, or add or remove style setters, we can do that all in one place and everywhere we use that style will be changed.

For example, if we want the text to be italic, we can add another setter to the Style:

<Style x:Key="redLargeTextStyle" TargetType="TextBlock">
    <Setter Property="Margin" Value="10,0,10,0"/>
    <Setter Property="Foreground" Value="{StaticResource redBrush}"/>
    <Setter Property="FontSize" Value="{ThemeResource TextStyleExtraLargeFontSize}"/>
    <Setter Property="FontStyle" Value="Italic"/>
</Style>

And then it looks like this:

image

You can override any property defined in the style by explicitly setting it on the control, like if we want the last line to be blue:

<TextBlock Foreground="Blue" Text="3rd line of text" Style="{StaticResource redLargeTextStyle}"/>

image

Now let’s say you wanted to have your style applied to all TextBlocks without setting the Style property on each of them. For this we can define an implicit style. This is easy enough to do, just don’t specify an x:Key value on your Style. Then this will be the default style for that type of control. Note that you can still override this by specifying a value for the Style property.

XAML 101: Creating your own Resources

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

A couple of posts ago, we looked at Themes and how you can use them to specify colors and other properties that would change with the currently selected theme. This was done through resource dictionaries, resource definitions and the ThemeResource markup extension.

The ThemeResources are used for consistency, but you may have consistency you want to enforce in your app to enforce the unique style of your app. Consider the following:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel>
        <TextBlock Text="Here is some text" Foreground="Red"/>
        <TextBlock Text="Some more text" Foreground="Red"/>
        <TextBlock Text="3rd line of text" Foreground="Red"/>
    </StackPanel>
</Grid>

And this is how it looks:

image

All the TextBlocks have a Foreground of Red, and this is fine and consistent, but if we wanted to change the foreground color, this is pretty fragile because we would need to change it in 3 places, and as the app grows, we would need to change it more.

A better way is to define a resource:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid.Resources>
        <SolidColorBrush x:Key="redBrush" Color="Red"/>
    </Grid.Resources>
    <StackPanel>
        <TextBlock Text="Here is some text" Foreground="{StaticResource redBrush}"/>
        <TextBlock Text="Some more text" Foreground="{StaticResource redBrush}"/>
        <TextBlock Text="3rd line of text" Foreground="{StaticResource redBrush}"/>
    </StackPanel>
</Grid>

The StaticResource markup extension will look for any resources with a matching x:Key in any parent element, or in an application-wide resource definition. If we want the resource definition to apply to the whole page,  then the resource definition can be at the page level:

<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">
    <Page.Resources>
        <SolidColorBrush x:Key="redBrush" Color="Red"/>
    </Page.Resources>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel>
            <TextBlock Text="Here is some text" Foreground="{StaticResource redBrush}"/>
            <TextBlock Text="Some more text" Foreground="{StaticResource redBrush}"/>
            <TextBlock Text="3rd line of text" Foreground="{StaticResource redBrush}"/>
        </StackPanel>
    </Grid>
</Page>

The most common case is probably that you would want this resource definition to be available anywhere in your app. To do this you can make the definition in your App.xaml file:

<Application
    x:Class="HelloXaml.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloXaml"
    RequestedTheme="Light">
    <Application.Resources>
        <SolidColorBrush x:Key="redBrush" Color="Red"/>
    </Application.Resources>
</Application>

XAML 101: The StackPanel

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

So far when looking at elements that contain other elements we have seen the Border and the Grid. Another useful container is the StackPanel. If you are familiar with Android development, the closest relation is to the LinearLayout control. The StackPanel lets you arrange elements in sequence one after the other either vertically or horizontally.

NOTE: When I was working closely with designers in Silverlight (a XAML based framework) they would usually take my StackPanels and convert them to Grids with Rows or Columns, they liked the level of control they had over the layout better. There are some drawbacks to StackPanel especially when it comes to horizontal StackPanels and fitting the available space. It’s usually not as much of a problem vertically and it is more common to use StackPanel in vertical mode. The StackPanel is an important component of ListView and other list based controls we will see later.

In the last post we had some text in the grid, but what if we wanted a few lines of text. One way to do this is to use a StackPanel:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel>
        <TextBlock Text="Here is some text"/>
        <TextBlock Text="Some more text"/>
        <TextBlock Text="3rd line of text"/>
    </StackPanel>
</Grid>

And this is how it looks:

image

The Orientation property on the StackPanel defaults to Vertical but we can change it to Horizontal:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="Here is some text"/>
        <TextBlock Text="Some more text"/>
        <TextBlock Text="3rd line of text"/>
    </StackPanel>
</Grid>

And here is how it looks:

image

I haven’t seen many cases where a Horizontal StackPanel is the best option. Usually there is a better solution, it could be a Grid with Columns, or a RelativePanel, we will see the RelativePanel soon.

XAML 101: Themes

Up until this point, we have been ignoring a piece of the XAML that is generated by default when a new Universal app is created. Consider this line:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

What’s with those curly braces and the content inside them in the Background property? First of all, the braces denote a XAML Markup Extension. There are several types of these, and we will see more in the future. This one is a ThemeResource markup extension. Markup extensions provide extra functionality when you need to do something other than specifying a value. The ThemeResource extension gives you consistency in your user interface by being able to specify predefined values for properties.

If you right click on ApplicationPageBackgroundThemeBrush and go to definition, you can see where it is defined.

image

This brings up a file called generic.xaml with this definition in it:

<SolidColorBrush x:Key="ApplicationPageBackgroundThemeBrush" Color="#FFFFFFFF" />

The x:Key property lets us reference this resource by name. This definition is inside a ResourceDictionary with an x:Key of “Light”:

<ResourceDictionary x:Key="Light">

This ResourceDictionary is inside a ThemeDictionaries property. There are two other ResourceDictionary entries here too, namely “Default”, and “HighContrast”. Default is used when the theme is set to the dark theme, and HighContrast is for when the device is in high contrast mode. The ThemeResource markup extension picks the right resource definition to use based on the key and the current theme.

NOTE: Themes were always a big reason for failures when submitting an app on Windows Phone 8.1 and earlier. Developers wouldn’t test their app in light theme (the default on Windows Phone was dark theme) and they would have text or other elements that wouldn’t be visible in light theme. Unless you forced it otherwise, on Windows Phone the theme for your app would follow what the user had selected for the system. Jeff Wilcox had a great tool for forcing the theme to a specific value http://www.jeff.wilcox.name/2012/01/phonethememanager/

In Windows 10, the developer has more control over the theme.

There are two different places where a theme is important. Once is at design time when we want to see how an app looks with a specific theme, and then when the app is run, so we can say what theme we prefer for our app. First let’s look at design time. If we have a MainPage.xaml file that has a Grid like this:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <TextBlock Text="Here is some text"/>
</Grid>

In the XAML designer in Visual Studio we see this:

image

See that gear at the top? If we click on that we get this:

image

If you change Theme to Dark you can see what your page will look like if the theme is set to dark:

image

Now this setting is only for design time. At run time, the app will default to light theme unless you specify otherwise. This is done in the App.xaml file, here is what is generated by default:

<Application
    x:Class="HelloXaml.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloXaml"
    RequestedTheme="Light">

</Application>

If you change RequestedTheme to “Dark”, then your app will use the dark theme. I think it’s a good idea to make sure your design time settings and the setting in App.xaml match so that you can see what it’s really going to look like.

XAML 101: Image Resizing with DecodePixelWidth and DecodePixelHeight

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.