WPF Simplified Part 11: XAML Tricks
February 12, 2010 5 Comments
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.
Pingback: WPF Simplified Series « I.Net
Hi
really nice and usefull blog, please keep the good work 🙂
How to create a Hashtable in XAML ? And bind it to a combobox ?
Pingback: C# wpf Can't create an array of objects - BlogoSfera
Pingback: C# wpf Can’t create an array of objects « news-rss feed form stackoverflow