Creating bidirectional apps for Windows Phone 8
[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]
This topic describes how you can create Windows Phone apps for right-to-left (RTL) or bidirectional languages.
Most of the languages that Windows Phone supports are read from left to right, but some of them such as Arabic, Hebrew, and Persian are read from right to left. Sometimes, RTL languages may contain content such as URLs or numbers that must be rendered as left to right. When left-to-right (LTR) content is used with RTL content in the same paragraph, each type of content is rendered in its own direction. We call this bidirectional content.
When you write a Windows Phone app for any of the RTL languages, consider the following points to help you make sure that your app works as intended.
This topic contains the following sections.
- Bidirectional content in Windows Phone
- Displaying right-to-left text
- Displaying right-to-left layout
- Displaying bidirectional content
- Displaying right-to-left images
- Displaying right-to-left shapes
- Related Topics
Bidirectional content in Windows Phone
As a guideline, when you write or localize an app for any RTL language, text and UI elements flow from the right. Also, to correctly display text, you must make sure UI elements, such as controls and images, also are rendered as intended.
The following illustration shows an example of bidirectional content on a Windows Phone device.
To help you specify how text and UI elements appear in RTL and bidirectional content scenarios, Windows Phone includes the FlowDirection property. You can set this property to one of the two enumeration values: LeftToRight or RightToLeft. The default FlowDirection value is LeftToRight. You can use this property with all elements that inherit from the FrameworkElement class.
Note
New project templates for managed Windows Phone 8 apps have language configuration for the RootFrame element that affects FlowDirection of an app for any of its supported languages. By default, an app that has added the supported culture for an RTL language will follow the traditional RTL FlowDirection on a phone that has a display language that’s set to that supported language. If your intention is to follow LTR alignment when your app is viewed using a phone set to a RTL display language, then you can add a supported culture for that language and use the default behavior without setting the FlowDirection of any element. Alternatively, if you have a reason to lock or dynamically shift the FlowDirection of part of your UI, explicitly setting FlowDirection for any child element will override the default setting in all cases.
Displaying right-to-left text
To display text from right to left, you can explicitly set the FlowDirection property to RightToLeft on the text control that you are using.
The following example shows how you can use the FlowDirection property to make the content flow from right to left in a RichTextBox control.
<StackPanel x:Name="LTRContentPanel" Grid.Row="0" Margin="0,10,0,-10">
<!-- 1) FlowDirection of the control inherited from default (LTR) -->
<RichTextBox FontSize="25" Height="119" Width="312">
<Paragraph>
<Run Text="Hello World!"/>
</Paragraph>
<Paragraph>
<Run Text="مرحبا العالم!"/>
</Paragraph>
</RichTextBox>
<!-- 2) FlowDirection of the control set to RTL -->
<RichTextBox FlowDirection="RightToLeft" Height="119" Width="312">
<Paragraph>
<Run Text="Hello World!"/>
</Paragraph>
<Paragraph>
<Run Text="مرحبا العالم!"/>
</Paragraph>
</RichTextBox>
</StackPanel>
The following illustration shows how the preceding code example renders.
Displaying right-to-left layout
In the preceding example, only the text within the RichTextBox control is displayed from right to left. You may also want some or all other controls and elements that you use in your app to have a RightToLeft flow. Because FlowDirection is inherited, you can set or override it at any point in the FrameElement hierarchy, from individual controls up to the RootFrame of the entire app.
The following example sets the FlowDirection property at the LayoutRoot grid so that the entire app flows from right to left except where the FlowDirection of a control is explicitly set to override that inherited setting.
<!--LayoutRoot is the root grid where all page content is placed-->
<!--FlowDirection for this sample is set in the LayoutRoot Grid:
<Grid x:Name="LayoutRoot" Background="Transparent" FlowDirection="RightToLeft">-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" Grid.RowSpan="2">
<!--THIS STACKPANEL INHERITS RTL-->
<StackPanel x:Name="RTLContentPanel" Grid.Row="0" Background="DarkGray" Margin="0,10,0,321">
<!--This control set to LTR-->
<RichTextBox FlowDirection="LeftToRight" FontSize="24 Height="53" Width="312" HorizontalAlignment="Left">
<Paragraph>
<Run Text="Hello World! مرحبا العالم!"/>
</Paragraph>
</RichTextBox>
<!--This control inherits RTL-->
<RichTextBox FontSize="24" Height="48" Width="312" HorizontalAlignment="Left">
<Paragraph>
<Run Text="Hello World! مرحبا العالم!"/>
</Paragraph>
</RichTextBox>
</StackPanel>
</Grid>
<Grid x:Name="xContentPanel" Grid.Row="1" Margin="12,0" Height="257" VerticalAlignment="Bottom">
<!--THIS STACKPANEL IS SET TO LTR-->
<StackPanel x:Name="LTRContentPanel" FlowDirection="LeftToRight" Margin="0,-28,0,45" Background="DarkGreen">
<!--This control inherits LTR-->
<RichTextBox FlowDirection="LeftToRight" FontSize="24" BorderBrush="AntiqueWhite" BorderThickness="2" Height="59" Width="312" HorizontalAlignment="Left">
<Paragraph>
<Run Text="Hello World! مرحبا العالم!"/>
</Paragraph>
</RichTextBox>
<!--This control is set to RTL-->
<RichTextBox FlowDirection="RightToLeft" FontSize="24" BorderBrush="AntiqueWhite" BorderThickness="2" Height="61" Width="312" HorizontalAlignment="Left">
<Paragraph>
<Run Text="Hello World! مرحبا العالم!"/>
</Paragraph>
</RichTextBox>
</StackPanel>
</Grid>
The following illustration shows how the preceding code example renders. Note that FlowDirection is inherited. The application and page titles align to the right because of their inheritance of RTL FlowDirection from LayoutRoot.
By default, the RightToLeftFlowDirection property of each element should be inherited from the LayoutRoot that contains all the controls. This example illustrates three aspects of FlowDirection behavior.The RichTextBox control and the Button control’s HorizontalAlignment are set to Left. When you set the FlowDirection to RightToLeft, the controls are aligned to the right.
Displaying bidirectional content
Sometimes RTL languages contain content that flows from left to right. For example, if you are displaying a network share name such as \\server1\folder\file.ext, you always want it to appear in the same way whether you are displaying it in Arabic or English. In such cases, you can use the Run element to separate the languages, and then set the FlowDirection property at the Run level.
The following example shows how you can display bidirectional content by setting the FlowDirection property at the Run level.
<StackPanel FlowDirection="RightToLeft" x:Name="TitlePanel" Grid.Row="0">
<TextBlock x:Name="ApplicationTitle" Text="Windows Phone" FontSize="20" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="bi-di Sample" FontSize="35" Margin="0,0,0,20" Style="{StaticResource PhoneTextTitle1Style}"/>
<StackPanel x:Name="ContentPanel" Grid.Row="1" >
<RichTextBox FlowDirection="RightToLeft" FontSize="25" BorderBrush="AntiqueWhite" BorderThickness="2" Height="300" Width="460" HorizontalAlignment="Left">
<Paragraph>
<Run>ثنائية الاتجاه المحتوى: </Run>
<Run FlowDirection="LeftToRight">\\wp8\efolder\filename.ppt</Run>
</Paragraph>
</RichTextBox>
</StackPanel>
</StackPanel>
The following illustration shows how the preceding code example renders.
Displaying right-to-left images
You can use a Image control to display an image in your Windows Phone app. To do this, use the control Source property to set the Uniform Resource Locator (URI) of the image you want to display.
Unlike other UI elements, a Image control does not inherit the FlowDirection value from its container. However, if you set the FlowDirection property directly on the Image control to a RightToLeft value, it appears flipped horizontally. This is because in most cases you would not want the image to be flipped, but in a few cases horizontally flipping the image produces the effect you want. If you specifically want the image to be flipped in your bidirectional app, set the FlowDirection property in your image to RightToLeft.
The following example has an Image element in a StackPanel control. The FlowDirection property of the StackPanel is set to RightToLeft.
<StackPanel FlowDirection="RightToLeft" x:Name="ContentPanel" Grid.Row="0">
<TextBlock x:Name="ApplicationTitle" Text="Windows Phone" FontSize="20" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="bi-di Sample" FontSize="35" Margin="0,0,0,20" Style="{StaticResource PhoneTextTitle1Style}"/>
<Image Source="microsoft.png" Height="100" Width="200" HorizontalAlignment="Left" />
</StackPanel>
The following illustration shows how the preceding code example renders. Notice that the Image element does not inherit the RightToLeft flow direction.
In the following example, the FlowDirection property is set to RightToLeft in the Image control.
<StackPanel FlowDirection="RightToLeft" x:Name="ContentPanel" Grid.Row="0">
<TextBlock x:Name="ApplicationTitle" Text="Windows Phone" FontSize="20" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="bi-di Sample" FontSize="35" Margin="0,0,0,20" Style="{StaticResource PhoneTextTitle1Style}"/>
<Image Source="microsoft.png" FlowDirection="RightToLeft" Height="100" Width="200" HorizontalAlignment="Left" />
</StackPanel>
The following illustration shows how the preceding code example renders. Notice that the Image control is flipped horizontally.
Displaying right-to-left shapes
You can use a Path object to draw a series of connected lines and curves. This works similarly to an Image control in its FlowDirection. For example, its RightToLeftFlowDirection property is a mirror image of its LeftToRight property. However, unlike an Image control, the Path inherits the FlowDirection property from its container. You don’t have to explicitly specify this in the Path class.
The following example draws a simple arrow using three lines. The arrow inherits RightToLeft flow direction from its parent StackPanel.
<StackPanel FlowDirection="RightToLeft" x:Name="ContentPanel" Grid.Row="0">
<TextBlock x:Name="ApplicationTitle" Text="Windows Phone" FontSize="20" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="bi-di Sample" FontSize="35" Margin="0,0,0,20" Style="{StaticResource PhoneTextTitle1Style}"/>
<Path Stroke="Blue" StrokeThickness="4">
<Path.Data>
<GeometryGroup>
<LineGeometry StartPoint="300,10" EndPoint="350,30" />
<LineGeometry StartPoint="10,30" EndPoint="352,30" />
<LineGeometry StartPoint="300,50" EndPoint="350,30" />
</GeometryGroup>
</Path.Data>
</Path>
</StackPanel>
The following illustration shows the output of the preceding code example.