次の方法で共有


WPF の双方向機能の概要

他の開発プラットフォームとは異なり、WPF には、双方向コンテンツの迅速な開発をサポートする多くの機能があります。たとえば、同じドキュメント内の左から右と右から左に混在するデータなどです。 同時に、WPF は、アラビア語やヘブライ語を話すユーザーなどの双方向機能を必要とするユーザーに優れたエクスペリエンスを作成します。

次のセクションでは、多くの双方向機能と、双方向コンテンツを最適に表示する方法を示す例について説明します。 ほとんどのサンプルでは XAML を使用しますが、C# または Microsoft Visual Basic コードに概念を簡単に適用できます。

FlowDirection

WPF アプリケーションのコンテンツ フローの方向を定義する基本的なプロパティは FlowDirection。 このプロパティは、 LeftToRight または RightToLeftの 2 つの列挙値のいずれかに設定できます。 このプロパティは、 FrameworkElementから継承するすべての WPF 要素で使用できます。

次の例では、 TextBox 要素のフロー方向を設定します。

左から右へのフロー方向

<TextBlock Background="DarkBlue" Foreground="LightBlue" 
   FontSize="20" FlowDirection="LeftToRight">
        This is a left-to-right TextBlock
</TextBlock>

右から左へのフロー方向

<TextBlock Background="LightBlue" Foreground="DarkBlue"
   FontSize="20" FlowDirection="RightToLeft">
        This is a right-to-left TextBlock
</TextBlock>

次の図は、前のコードがどのようにレンダリングされるかを示しています。

さまざまな流れの方向を示す図。

ユーザー インターフェイス (UI) ツリー内の要素は、そのコンテナーから FlowDirection を継承します。 次の例では、TextBlockGridに存在するWindow内にあります。 FlowDirectionWindowを設定することは、GridTextBlockにも設定を意味します。

次の例では、 FlowDirectionの設定を示します。

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="FlowDirectionApp.Window1"
    Title="BidiFeatures" Height="200" Width="700" 
    FlowDirection="RightToLeft">
     
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
      </Grid.ColumnDefinitions>
      <TextBlock Grid.Column="0" >
          This is a right-to-left TextBlock
      </TextBlock>

      <TextBlock Grid.Column="1" FlowDirection="LeftToRight">
          This is a left-to-right TextBlock
      </TextBlock>
    </Grid>
</Window>

最上位レベル Window には RightToLeftFlowDirectionがあるため、その中に含まれるすべての要素も同じ FlowDirectionを継承します。 要素が指定されたFlowDirectionをオーバーライドするには、前の例での2番目のTextBlockLeftToRightに変わるように、明示的な方向変更を追加する必要があります。 FlowDirectionが定義されていない場合、既定のLeftToRightが適用されます。

次の図は、前の例の出力を示しています。

明示的なフロー方向の変更を示す図。

フロウドキュメント

HTML、Win32、Java などの多くの開発プラットフォームでは、双方向コンテンツ開発を特別にサポートしています。 HTML などのマークアップ言語は、コンテンツ ライターに、必要な方向にテキストを表示するために必要なマークアップを提供します。たとえば、HTML 4.0 タグ、"dir" ("rtl" または "ltr" を値として受け取る) などです。 このタグは FlowDirection プロパティに似ていますが、 FlowDirection プロパティはテキスト コンテンツのレイアウトをより高度な方法で動作し、テキスト以外のコンテンツに使用できます。

テキスト、テーブル、イメージ、およびその他の要素の組み合わせをホストできる UI 要素。 次のセクションのサンプルでは、この要素を使用します。

FlowDocumentへのテキストの追加は、それ以上の方法で行うことができます。 これを行う簡単な方法は、テキストなどのコンテンツをグループ化するために使用されるブロック レベルの要素である Paragraph を使用することです。 インライン レベルの要素にテキストを追加するには、サンプルで SpanRunを使用します。 Span は、他のインライン要素をグループ化するために使用されるインライン レベルのフロー コンテンツ要素ですが、 Run は、書式設定されていないテキストの実行を含むインライン レベルのフロー コンテンツ要素です。 Spanには、複数のRun要素を含めることができます。

最初のドキュメントの例には、多数のネットワーク共有名を持つドキュメントが含まれています。たとえば、 \\server1\folder\file.ext。 アラビア語または英語のドキュメントにこのネットワーク リンクがある場合でも、常に同じ方法で表示する必要があります。 次の図は、Span 要素の使用方法を示し、アラビア語の RightToLeft ドキュメントのリンクを示しています。

Span 要素の使用を示す図。

テキストは RightToLeftされているため、"\" などの特殊文字はすべて右から左の順序で区切ります。 その結果、リンクが正しい順序で表示されないため、問題を解決するには、テキストを埋め込んで、別の Run フロー LeftToRightを保持する必要があります。 問題を解決するには、言語ごとに個別の Run を使用する代わりに、使用頻度の低い英語のテキストをより大きなアラビア語の Spanに埋め込む方が適しています。

次の図は、Span 要素に埋め込まれた Run 要素を使用してこれを示しています。

Span 要素に埋め込まれた Run 要素を示す図。

次の例では、ドキュメントで Run 要素と Span 要素を使用する方法を示します。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    FlowDirection="RightToLeft">

  <FlowDocument>
    <Paragraph>
      <Span FlowDirection="RightToLeft" >
        ستجد الملف هنا:
        <Run FlowDirection="LeftToRight">
           \\server1\filename\filename1.txt</Run>
        ثم باقى النص!
      </Span>
    </Paragraph>
  </FlowDocument>
</Page>

Span 要素

Span要素は、フロー方向が異なるテキスト間の境界区切り記号として機能します。 フロー方向が同じSpan要素でも、双方向スコープが異なると見なされます。つまり、Span要素はコンテナーのFlowDirectionで順序付けされ、Span要素内のコンテンツのみがFlowDirectionSpanに従います。

次の図は、複数の TextBlock 要素の流れの方向を示しています。

フロー方向が異なるテキスト ブロックを示す図。

次の例は、 Span 要素と Run 要素を使用して、前の図に示した結果を生成する方法を示しています。

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <StackPanel >

    <TextBlock FontSize="20" FlowDirection="RightToLeft">
      <Run FlowDirection="LeftToRight">العالم</Run>
      <Run FlowDirection="LeftToRight" Foreground="Red" >فى سلام</Run>
    </TextBlock>

    <TextBlock FontSize="20" FlowDirection="LeftToRight">
      <Run FlowDirection="RightToLeft">العالم</Run>
      <Run FlowDirection="RightToLeft" Foreground="Red" >فى سلام</Run>
    </TextBlock>

    <TextBlock FontSize="20" Foreground="Blue">العالم فى سلام</TextBlock>

    <Separator/>

    <TextBlock FontSize="20" FlowDirection="RightToLeft">
      <Span Foreground="Red" FlowDirection="LeftToRight">Hello</Span>
      <Span FlowDirection="LeftToRight">World</Span>
    </TextBlock>

    <TextBlock FontSize="20" FlowDirection="LeftToRight">
      <Span Foreground="Red" FlowDirection="RightToLeft">Hello</Span>
      <Span FlowDirection="RightToLeft">World</Span>
    </TextBlock>

    <TextBlock FontSize="20" Foreground="Blue">Hello World</TextBlock>

  </StackPanel>

</Page>

サンプルの TextBlock 要素では、 Span 要素は親の FlowDirection に従ってレイアウトされますが、各 Span 要素内のテキストは独自の FlowDirectionに従って流れます。 これは、ラテン語とアラビア語、またはその他の言語に適用されます。

xml:lang の追加

次の図は、数値と算術式 ( "200.0+21.4=221.4"など) を使用する別の例を示しています。 FlowDirectionのみが設定されていることに注意してください。

FlowDirection のみを使用して数値を表示するグラフィック。

このアプリケーションのユーザーは、FlowDirection が正しいにもかかわらず、数字がアラビア数字として正しく整形されていないため、出力に失望するでしょう。

XAML 要素には、各要素の言語を定義する XML 属性 (xml:lang) を含めることができます。 XAML では、ツリー内の親要素に適用 xml:lang 値が子要素によって使用される XML 言語原則もサポートされています。 前の例では、 Run 要素またはその最上位要素に言語が定義されていないため、既定の xml:lang が使用されました。これは XAML に en-US されています。 Windows Presentation Foundation (WPF) の内部数値整形アルゴリズムは、対応する言語 (この場合は英語) で数値を選択します。 アラビア数字を正しく表示するには、 xml:lang を設定する必要があります。

次の図は、 xml:lang が追加された例を示しています。

右から左に流れるアラビア数字を示す図。

次の例では、アプリケーションに xml:lang を追加します。

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    FlowDirection="RightToLeft">
      <FlowDocument>
         <Paragraph>
            <Span FlowDirection="RightToLeft" Language="ar-SA">
              العملية الحسابية: "200.0+21.4=221.4"
            </Span>
         </Paragraph>
      </FlowDocument>
</Page>

多くの言語では、xml:lang"ar-SA"はアラビア語の 2 つのバリエーションを表すなど、対象となる地域によって異なる"ar-EG"値を持つことに注意してください。 前の例では、 xml:lang 値と FlowDirection 値の両方を定義する必要があることを示しています。

テキスト以外の要素を含む FlowDirection

FlowDirection は、テキスト要素内のテキストの流れ方だけでなく、ほぼすべての他の UI 要素のフロー方向も定義します。 次の図は、水平方向のToolBarを使用して背景を左から右のグラデーションで描画するLinearGradientBrushを示しています。

左から右のグラデーションのツール バーを示すグラフィック。

FlowDirectionRightToLeft に設定すると、ToolBar ボタンは右から左に配置されるだけでなく、LinearGradientBrushでもオフセットが右から左に再調整されます。

次の図は、 LinearGradientBrushの再調整を示しています。

右から左へのグラデーションを持つツール バーを示すグラフィック。

次の例では、 RightToLeftToolBarを描画します。 (左から右に描画するには、FlowDirectionToolBar属性を削除します。

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  
  <ToolBar FlowDirection="RightToLeft" Height="50" DockPanel.Dock="Top">
    <ToolBar.Background>
      <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,1">
        <LinearGradientBrush.GradientStops>
          <GradientStop Color="DarkRed" Offset="0" />
          <GradientStop Color="DarkBlue" Offset="0.3" />
          <GradientStop Color="LightBlue" Offset="0.6" />
          <GradientStop Color="White" Offset="1" />
        </LinearGradientBrush.GradientStops>
      </LinearGradientBrush>
    </ToolBar.Background>

    <Button FontSize="12" Foreground="White">Button1</Button>
    <Rectangle Width="20"/>
    <Button FontSize="12" Foreground="White">Button2</Button>
    <Rectangle Width="20"/>
    <Button FontSize="12" Foreground="White">Button3</Button>
    <Rectangle Width="20"/>
    <Button FontSize="12" Foreground="White">Button4</Button>
    <Rectangle Width="20"/>
  </ToolBar>
</Page>

FlowDirection に関する例外処理

FlowDirectionが期待どおりに動作しない場合がいくつかあります。 このセクションでは、次の 2 つの例外について説明します。

イメージ

Imageは、画像を表示するコントロールを表します。 XAML では、表示するSourceの URI (Uniform Resource Identifier) を定義するImage プロパティと共に使用できます。

他の UI 要素とは異なり、 Image はコンテナーから FlowDirection を継承しません。 ただし、 FlowDirection が明示的に RightToLeft に設定されている場合、 Image は水平方向に反転して表示されます。 これは、双方向コンテンツの開発者にとって便利な機能として実装されています。場合によっては、画像を水平方向に反転すると目的の効果が得られるからです。

次の図は、反転された Imageを示しています。

反転された画像を示す図。

次の例は、 ImageFlowDirection を含む StackPanel から継承できない場合を示しています。

この例を実行するには、 C :\ ドライブにms_logo.jpgという名前のファイルが必要です。

<StackPanel 
  xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' 
  FlowDirection="RightToLeft">

  <Image Source="file://c:/ms_logo.jpg" 
         Width="147" Height="50"/>
  <Separator Height="10"/>
  <Image Source="file://c:/ms_logo.jpg" 
         Width="147" Height="50" FlowDirection="LeftToRight" />
  <Separator Height="10"/>
  <Image Source="file://c:/ms_logo.jpg" 
         Width="147" Height="50" FlowDirection="RightToLeft"/>
</StackPanel>

ダウンロード ファイルには、 ms_logo.jpg ファイルが含まれています。 このコードでは、.jpg ファイルがプロジェクト内ではなく C:\ ドライブのどこかにあることを前提としています。 プロジェクト ファイルから C:\ ドライブに .jpg をコピーするか、コードを変更してプロジェクト内のファイルを検索する必要があります。 この変更を行うには、Source="file://c:/ms_logo.jpg"Source="ms_logo.jpg"に変更してください。

パス

Imageに加えて、もう 1 つの興味深い要素がPath。 Path は、接続された一連の線と曲線を描画できるオブジェクトです。 Imageに関するFlowDirectionに似た方法で動作します。たとえば、RightToLeftFlowDirectionLeftToRightの水平ミラーです。 ただし、 Imageとは異なり、 Path はコンテナーから FlowDirection を継承し、明示的に指定する必要はありません。

次の例では、3 本の線を使用して単純な矢印を描画します。 最初の矢印はRightToLeftからStackPanel流れの方向を継承するため、始点と終点は右側の基点から測定されます。 明示的な RightToLeftFlowDirection を持つ 2 番目の矢印も右側から始まります。 ただし、3 番目の矢印の左側には開始ルートがあります。 描画の詳細については、「 LineGeometryGeometryGroup」を参照してください。

<StackPanel 
  xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' 
  FlowDirection="RightToLeft">

  <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>

  <Path Stroke="Red" StrokeThickness="4" FlowDirection="RightToLeft">
    <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>
 
  <Path Stroke="Green" StrokeThickness="4" FlowDirection="LeftToRight">
    <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>

次の図は、 Path 要素を使用して矢印が描画された前の例の出力を示しています。

Path 要素を使用して描画された矢印を示す図。

ImagePathは、WPF がFlowDirectionを使用する方法の 2 つの例です。 コンテナー内の特定の方向に UI 要素をレイアウトするだけでなく、FlowDirectionは、サーフェス、InkPresenterLinearGradientBrushにインクをレンダリングするRadialGradientBrushなどの要素と共に使用できます。 左から右の動作を模倣するコンテンツの右から左への動作が必要な場合、またはその逆が必要な場合は常に、Windows Presentation Foundation (WPF) でその機能が提供されます。

数値の置換

これまで、Windows では、同じ数字に対して異なるカルチャ図形を表現できるようにすることで数値の置換がサポートされていましたが、これらの数字の内部ストレージはさまざまなロケール間で統一され、たとえば、数値は既知の 16 進値 (0x40、0x41) に格納されますが、選択した言語に従って表示されます。

これにより、アプリケーションは、ある言語から別の言語に変換することなく数値を処理できます。たとえば、ユーザーはローカライズされたアラビア語の Windows で Microsoft Excel スプレッドシートを開き、アラビア語で整形された数字を表示できますが、ヨーロッパ版の Windows で開き、同じ数値のヨーロッパの表現を表示できます。 これは、コンマ区切り記号やパーセント記号などの他の記号にも必要です。これは、通常、同じドキュメント内の数値に付随するためです。

Windows Presentation Foundation (WPF) は引き続き同じ伝統を持ち、置換のタイミングと使用方法をよりユーザーが制御できるようにするこの機能のサポートをさらに追加します。 この機能は任意の言語向けに設計されていますが、双方向コンテンツでは特に便利です。アプリケーションが実行される可能性のあるさまざまなカルチャのため、通常、特定の言語の数字を整形することはアプリケーション開発者にとって困難です。

Windows Presentation Foundation (WPF) での数値置換の動作を制御するコア プロパティは、 Substitution 依存関係プロパティです。 NumberSubstitution クラスは、テキスト内の数値を表示する方法を指定します。 動作を定義する 3 つのパブリック プロパティがあります。 各プロパティの概要を次に示します。

CultureSource:

このプロパティは、数値のカルチャを決定する方法を指定します。 3 つの NumberCultureSource 列挙値のいずれかを受け取ります。

CultureOverride:

CultureOverride プロパティは、CultureSource プロパティが Override に設定され、それ以外の場合は無視される場合にのみ使用されます。 数値カルチャを指定します。 既定値である null の値は、en-USとして解釈されます。

置換:

このプロパティは、実行する数値置換の種類を指定します。 次のいずれかの NumberSubstitutionMethod 列挙値を受け取ります。

  • AsCulture: 置換方法は、数値カルチャの NumberFormatInfo.DigitSubstitution プロパティに基づいて決定されます。 これが既定値です。

  • Context: 数値カルチャがアラビア語またはペルシャ語のカルチャの場合は、数字がコンテキストに依存することを指定します。

  • European: 数値は常にヨーロッパの数字としてレンダリングされます。

  • NativeNational: 数値は、文化のNumberFormatで指定された、数値文化の国の数字を使用して描画されます。

  • Traditional: 数値は、数値カルチャの従来の数字を使用してレンダリングされます。 ほとんどの文化では、これは NativeNationalと同じです。 ただし、 NativeNational 一部のアラビア語のカルチャではラテン数字になりますが、この値はすべてのアラビア語のカルチャではアラビア数字になります。

双方向コンテンツ開発者にとって、これらの値は何を意味しますか? ほとんどの場合、開発者は、 FlowDirection と各テキスト UI 要素の言語のみを定義する必要があります (たとえば、 Language="ar-SA"NumberSubstitution ロジックは、正しい UI に従って数値を表示します。 次の例では、アラビア語バージョンの Windows で実行されている Windows Presentation Foundation (WPF) アプリケーションでアラビア語と英語の数字を使用する方法を示します。

<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
  <StackPanel>
   <TextBlock Background="LightGreen" FontSize="32" 
      Language="ar-SA" FlowDirection="RightToLeft">1+2=3</TextBlock>
   <TextBox Background="LightGreen" FontSize="32" 
      Language="ar-SA" FlowDirection="RightToLeft">1+2=3</TextBox>
   <TextBlock Background="LightBlue" FontSize="32">1+2=3</TextBlock>
   <TextBox Background="LightBlue" FontSize="32">1+2=3</TextBox>
 </StackPanel>
</Page>

次の図は、アラビア語と英語の数字が表示されたアラビア語バージョンの Windows で実行している場合の、前のサンプルの出力を示しています。

アラビア語と英語の数字を示す図。

代わりにFlowDirectionFlowDirectionに設定するとヨーロッパの数字が生成されるため、この場合はLeftToRightが重要でした。 次のセクションでは、文書全体で数字を統一表示する方法について説明します。 この例がアラビア語の Windows で実行されていない場合、すべての数字はヨーロッパの数字として表示されます。

置換規則の定義

実際のアプリケーションでは、プログラムで言語を設定する必要がある場合があります。 たとえば、 xml:lang 属性をシステムの UI で使用される属性と同じに設定したり、アプリケーションの状態に応じて言語を変更したりできます。

アプリケーションの状態に基づいて変更を加える場合は、Windows Presentation Foundation (WPF) によって提供されるその他の機能を使用します。

まず、アプリケーション コンポーネントの NumberSubstitution.CultureSource="Text"を設定します。 この設定を使用すると、 TextBlockなど、"User" が既定値であるテキスト要素の UI から設定が取得されないようにします。

例えば次が挙げられます。

<TextBlock
   Name="text1" NumberSubstitution.CultureSource="Text">
   1234+5679=6913
</TextBlock>

対応する C# コードで、たとえば、 Language プロパティを "ar-SA" に設定します。

text1.Language = System.Windows.Markup.XmlLanguage.GetLanguage("ar-SA");

Language プロパティを現在のユーザーの UI 言語に設定する必要がある場合は、次のコードを使用します。

text1.Language = System.Windows.Markup.XmlLanguage.GetLanguage(System.Globalization.CultureInfo.CurrentUICulture.IetfLanguageTag);

CultureInfo.CurrentCulture は、実行時に現在のスレッドによって使用される現在のカルチャを表します。

最終的な XAML の例は、次の例のようになります。

<Page x:Class="WindowsApplication.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Code Sample" Height="300" Width="300"
>
    <StackPanel>
      <TextBlock Language="ar-SA" 
         FlowDirection="RightToLeft">عربى: 1+2=3
      </TextBlock>
      <TextBlock Language="ar-SA" 
         FlowDirection="RightToLeft" 
         NumberSubstitution.Substitution="European">عربى: 1+2=3 
      </TextBlock>
    </StackPanel>
</Page>

最終的な C# の例は、次のようになります。

namespace BidiTest
{
    public partial class Window1 : Window
    {

        public Window1()
        {
            InitializeComponent();

            string currentLanguage =
                System.Globalization.CultureInfo.CurrentCulture.IetfLanguageTag;

            text1.Language = System.Windows.Markup.XmlLanguage.GetLanguage(currentLanguage);

            if (currentLanguage.ToLower().StartsWith("ar"))
            {
                text1.FlowDirection = FlowDirection.RightToLeft;
            }
            else
            {
                text1.FlowDirection = FlowDirection.LeftToRight;
            }
        }
    }
}

次の図は、どちらのプログラミング言語でも、アラビア数字を表示するウィンドウの外観を示しています。

アラビア数字を表示する図。

代入プロパティの使用

Windows Presentation Foundation (WPF) での数値置換の動作方法は、テキスト要素の言語とその FlowDirectionの両方によって異なります。 FlowDirectionが左から右の場合、ヨーロッパの数字がレンダリングされます。 ただし、前にアラビア語のテキストが付いている場合、または言語が "ar" に設定されていて、 FlowDirectionRightToLeftされている場合は、代わりにアラビア数字がレンダリングされます。

ただし、すべてのユーザーに対してヨーロッパの数字などの統合アプリケーションを作成したい場合もあります。 または、特定のTableStyleセル内のアラビア数字。 これを行う簡単な方法の 1 つは、 Substitution プロパティを使用する方法です。

次の例では、最初の TextBlock には Substitution プロパティが設定されていないため、アルゴリズムによってアラビア数字が想定どおりに表示されます。 ただし、2 番目の TextBlockでは、置換がヨーロッパに設定され、アラビア数字の既定の置換がオーバーライドされ、ヨーロッパの数字が表示されます。

<Page x:Class="WindowsApplication.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Code Sample" Height="300" Width="300"
>
    <StackPanel>
      <TextBlock Language="ar-SA" 
         FlowDirection="RightToLeft">عربى: 1+2=3
      </TextBlock>
      <TextBlock Language="ar-SA" 
         FlowDirection="RightToLeft" 
         NumberSubstitution.Substitution="European">عربى: 1+2=3 
      </TextBlock>
    </StackPanel>
</Page>