One of the random things I’ve learned about while working on WPF/Avalon are the different number systems used through out the world. I wrote a XAML example that shows some the support for number substitution. Here’s a screenshot and the markup:

<Border xmlns="http://schemas.microsoft.com/winfx/avalon/2005" xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005"
Padding="10" HorizontalAlignment="Center" VerticalAlignment="Center" BorderBrush="#ccc" BorderThickness="1">
<Grid HorizontalAlignment="Center">
<Grid.Resources>
<!-- Common properties for all TextBlock elements -->
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontFamily" Value="Constantia" />
<Setter Property="FontSize" Value="20" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Margin" Value="5" />
</Style>
<!-- Properties for the number display, the databinding is done here -->
<Style x:Key="NumberDisplay" TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="NumberSubstitution.Substitution" Value="Traditional" />
<Setter Property="Text" Value="{Binding Path=Value, ElementName=NumberSlider}" />
<Setter Property="Grid.Column" Value="1" />
<Setter Property="MinWidth" Value="50" />
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Title and Slider -->
<StackPanel Grid.ColumnSpan="2">
<TextBlock Grid.ColumnSpan="2" FontWeight="Bold" FontFamily="Candara" FontSize="30">Number Substitution</TextBlock>
<Slider Grid.ColumnSpan="2" Minimum="0" Maximum="10" Name="NumberSlider" IsSnapToTickEnabled="True" TickFrequency=".01" Width="Auto" MaxWidth="300" Margin="10" />
</StackPanel>
<!-- Row Shading -->
<Rectangle Grid.Row="1" Grid.ColumnSpan="2" Fill="#dec" />
<Rectangle Grid.Row="2" Grid.ColumnSpan="2" Fill="#ffd" />
<Rectangle Grid.Row="3" Grid.ColumnSpan="2" Fill="#dec" />
<Rectangle Grid.Row="4" Grid.ColumnSpan="2" Fill="#ffd" />
<Rectangle Grid.Row="5" Grid.ColumnSpan="2" Fill="#dec" />
<!-- Labels -->
<TextBlock Grid.Row="1">English (en-us)</TextBlock>
<TextBlock Grid.Row="2">Portuguese (pt-pt)</TextBlock>
<TextBlock Grid.Row="3">Arabic (ar-sa)</TextBlock>
<TextBlock Grid.Row="4">Thai (th-th)</TextBlock>
<TextBlock Grid.Row="5">Panjabi (pa-in)</TextBlock>
<!-- Numbers -->
<TextBlock Grid.Row="1" xml:lang="en-us" Style="{StaticResource NumberDisplay}" />
<TextBlock Grid.Row="2" xml:lang="pt-pt" Style="{StaticResource NumberDisplay}" />
<TextBlock Grid.Row="3" xml:lang="ar-sa" Style="{StaticResource NumberDisplay}" />
<TextBlock Grid.Row="4" xml:lang="th-th" Style="{StaticResource NumberDisplay}" />
<TextBlock Grid.Row="5" xml:lang="pa-in" Style="{StaticResource NumberDisplay}" />
</Grid>
</Border>
You can copy and paste the code into XamlPad and manipulate the slider in order to see the changing values live (which is pretty neat in a very nerdy way).
The markup may look large, but that’s mostly my formatting (because I like to make things look pretty). Here’s a simplified excerpt to show the important part:
<TextBlock xml:lang="ar-sa" NumberSubstitution.Substitution="Traditional" />
The snippet above does two things. First it sets the culture of the content being displayed in the TextBlock, in this case Saudi Arabic (ar-sa). In order to activate the number substitution in this sample, we also have to set the NumberSubstitution.Substitution property to Traditional, which tells the system to look at the culture of the current context, instead of the system setting.
I’ll close this entry with a second screenshot, showing a different number this time:

Update 10/28: Norris Cheng, a fellow Avalon team member, pointed out something I should clarify/correct in this entry (which I’ve paraphrased below):
The
NumberSubstitution.CultureSourcetells the system whichCultureInfoit should look at:xml:lang(the default), the user’s machine setting, or theNumberSubstitution.CultureOverrideproperty. The reason we setNumberSubstitution.Substitution(which should really be calledSubstitutionMethodis that even for cultures likear-SA, latin digits are used by default — you need to setNumberSubstitution.SubstitutiontoTraditionalto tell the system to use the traditional digits instead.