WPF Simplified Part 11: XAML Tricks

The Extensible Application Markup Language (aka XAML) is a declarative programming language that was specifically built for WPF to encourage separation of front-end appearance and back-end logic.

While a full explanation of XAML is beyond the scope of this post (see here for an introduction), we’ll focus on some uncommon features of XAML,

1. Escaping curly braces: Say you want to display curly braces in XAML,

        <!-- Error! -->
        <TextBlock Text="{test string}" />

will fail because the parser thinks that the string is a markup extension. There are two ways to fix this,

    a. Escape the curly braces:

    <TextBlock Text="{}{test string}" />

    b. Use the property element syntax:

    <TextBlock>{test string}</TextBlock>

2. Procedural code inside XAML: You can embed code inside your XAML file, though its not recommended.

    <Button x:Name="MyButton" Height="100" Width="100" Click="MyButton_Click" />
    <x:Code>
        <![CDATA[ 
            private void MyButton_Click(Object sender, RoutedEventArgs e) { 
                MessageBox.Show("Button click!"); 
            } 
        ]]>
    </x:Code>

3. Preserve white space: Say you want to preserve white spaces between text,

     <TextBlock>Text     spacing</TextBlock>

this will collapse the space between ‘Text’ and ‘spacing’, to preserve the spaces try this,

     <TextBlock xml:space="preserve">Text     spacing</TextBlock>

or simply,

    <TextBlock Text="Text     spacing" /> 

4. Use null in XAML: You can specify null in XAML using the x:Null markup extension,

    <Grid Background="{x:Null}">

5. Use StringFormat in XAML: Very useful for quick formatting,

    <TextBlock Text="{Binding Name, StringFormat=Hello {0}!!}" />
    <TextBlock Text="{Binding Date, StringFormat=Today\'s date is: {0:MM/dd/yyyy}}" />

6. Use MultiBinding with StringFormat:

    <TextBlock> 
        <TextBlock.Text> 
            <MultiBinding StringFormat="Name:{0}, Age:{1}"> 
                <Binding Path="Name" /> 
                <Binding Path="Age" /> 
            </MultiBinding> 
        </TextBlock.Text>
    </TextBlock>

7. Create an array in XAML: You can create an array in XAML,

    <ListBox>
        <ListBox.ItemsSource>
            <x:Array Type="{x:Type sys:String}">
                <sys:String>John</sys:String>
                <sys:String>Paul</sys:String>
                <sys:String>Andy</sys:String>
            </x:Array>
        </ListBox.ItemsSource>
    </ListBox>

where,

    xmlns:sys="clr-namespace:System;assembly=mscorlib"

In fact you can use other data types from the System namespace, like Int32, Boolean, and even DateTime,

    <ListBox>
        <ListBox.ItemsSource>
            <x:Array Type="{x:Type sys:DateTime}">
                <sys:DateTime>1/1/10</sys:DateTime>
                <sys:DateTime>3/3/10 03:21 PM</sys:DateTime>
            </x:Array>
        </ListBox.ItemsSource>
    </ListBox>

8. Specify an empty string in XAML:

    <ListBox>
        <ListBox.ItemsSource>
            <x:Array Type="{x:Type sys:String}">
                <sys:String>John</sys:String>
                <x:Static Member="sys:String.Empty" />
                <sys:String>Andy</sys:String>
            </x:Array>
        </ListBox.ItemsSource>
    </ListBox>
 

where,

    xmlns:sys="clr-namespace:System;assembly=mscorlib"

9. Put constants in XAML: Say you have a constant in code,

    public static string Extension = ".xaml"  //In class Window1
 

You can use this in XAML via the x:Static markup extension, like this,

    <TextBlock Text="{x:Static local:Window1.Extension}" />

where,

    xmlns:local="clr-namespace:WpfApplication1"

In fact, you can assign any static value,

    <Label Content="{x:Static sys:DateTime.Now}" />
    <Label Foreground="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />

10. Instantiate a class in XAML: Say you have the following class in your code,

    public class Person {
        public string Name { get; set; }
        public int Age { get; set; }
    }

You can instantiate an array in XAML, populate it with Person type objects and bind to a listbox,

    <Grid.Resources>
        <!-- Create a array of Person objects -->
        <x:Array x:Key="Office" Type="{x:Type local:Person}">
            <!-- Instantiate a Person and add to the array -->
            <local:Person Name="Michael" Age="40"/>
            <local:Person Name="Jim" Age="30"/>
            <local:Person Name="Dwight" Age="30"/>
        </x:Array>
    </Grid.Resources>
    
    <!-- Bind the array to the listbox -->
    <ListBox ItemsSource="{Binding Source={StaticResource Office}}" DisplayMemberPath="Name" />

If you have a collection,

    public class Family : ObservableCollection<Person> {
        public Family() {
            Add(new Person() { Name = "Jim", Age = 30 });
            Add(new Person() { Name = "Pam", Age = 30 });
        }
    }

we can instantiate the collection in XAML and then bind to it,

    <Grid.Resources>
        <!-- Instantiate the Family class -->
        <local:Family x:Key="Family" />
    </Grid.Resources>
    <!-- Bind to the collection -->
    <ListBox ItemsSource="{Binding Source={StaticResource Family}}" DisplayMemberPath="Name" />

See more XAML tricks here.

Digg This

About soumya chattopadhyay
I live and work in Seattle, WA. I work with Microsoft technologies, and I'm especially interested in C#.

5 Responses to WPF Simplified Part 11: XAML Tricks

  1. Pingback: WPF Simplified Series « I.Net

  2. Mr-H says:

    Hi
    really nice and usefull blog, please keep the good work 🙂

  3. Anjum S Khan says:

    How to create a Hashtable in XAML ? And bind it to a combobox ?

  4. Pingback: C# wpf Can't create an array of objects - BlogoSfera

  5. Pingback: C# wpf Can’t create an array of objects « news-rss feed form stackoverflow

Leave a comment