Поделиться через


Общие сведения о двусторонних возможностях в WPF

Обновлен: Ноябрь 2007

В отличие от любых других платформ разработки, WPF имеет множество возможностей, поддерживающих быструю разработку двунаправленного содержимого, например, данных, смешанных слева направо и справа налево, в одном и том же документе. В то же время WPF дает отличный опыт пользователям, которым необходимы двунаправленные возможности, например, пользователям, говорящим на иврите и арабском языке.

В следующих разделах объясняются многие двунаправленные возможности, приводятся примеры, иллюстрирующие способы достижения наилучшего отображения на экране двунаправленного содержимого. Большинство образцов использует XAML, хотя принцип можно легко применить к коду C# или Microsoft Visual Basic.

В этом разделе содержатся следующие подразделы.

  • FlowDirection
  • FlowDocument
  • Элементы Span
  • FlowDirection с нетекстовыми элементами
  • Подстановка чисел

FlowDirection

Основным свойством, определяющим направление потока содержимого в приложении WPF, является FlowDirection. Этому свойству может быть присвоено одно из двух значений перечисления, LeftToRight или RightToLeft. Свойство доступно для всех элементов WPF, которые наследуют из FrameworkElement.

Aa350685.alert_note(ru-ru,VS.90).gifПримечание.

Все рисунки в этом разделе показывают код и отображение кода в средстве XAMLPad. Кроме того, в большинстве случаев предоставляемый пример можно загрузить.

В следующих примерах задается направление потока элемента 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>

Полный пример см. в разделе Пример задания направления текста (LeftToRight и RightToLeft).

Приведенный ниже рисунок показывает как предыдущий код визуализирует.

Пример FlowDirection

Выравнивание TextBlock

Элемент в дереве пользовательский интерфейс будут наследовать FlowDirection из контейнера. В следующем примере TextBlock находится внутри Grid, который постоянно хранится в Window. Задание FlowDirection для Window подразумевает его задание как для Grid, так и для TextBlock.

Следующий пример демонстрирует установку FlowDirection.

<Window
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://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, к элементу необходимо добавить явное изменение направления, такое как второй TextBlock в предыдущем примере, который изменяется на LeftToRight. Когда не определен FlowDirection, применяется значение по умолчанию LeftToRight.

Полный пример см. в разделе Пример использования свойства FlowDirection.

На следующем рисунке показаны выходные данные предыдущего примера.

Пример явно заданного FlowDirection

Иллюстрация направления потока

FlowDocument

Многие платформы разработки, такие как HTML, Win32 и Java™, обеспечивают специальную поддержку развития двунаправленного содержимого. Языки разметки, такие как HTML, предоставляют редакторы записи необходимой разметки для отображения на экране текста в любом требуемом направлении, например, тег 4.0 HTML, “dir”, которая принимает значения “rtl” или “ltr”. Этот тег аналогичен свойству FlowDirection, но свойство FlowDirection предоставляет более прогрессивный способ доступа к текстовому содержимому макета и может быть использовано для иного чем текст содержимого.

В WPF элемент FlowDocument является универсальным элементом Пользовательский интерфейс, который может размещать сочетания текста, таблиц, изображений и других элементов. В следующих разделах примеры используют этот элемент.

Добавление текста к FlowDocument можно быть осуществлено несколькими способами. Простой способ добавить текст — сделать это через Paragraph, который является элементом блочного уровня, используемого для группировки такого содержимого, как текст. Чтобы добавить текст в элементы встроенного уровня, примеры используют Span и Run. Span является элементов поточного содержимого встроенного уровня, использующегося для группировки других встроенных элементов, пока Run является элементом поточного содержимого встроенного уровня, предназначенного для содержания выполнения неформатированного текста. Span может содержать несколько элементов Run.

Первый пример документа содержит документ, имеющий несколько сетевых совместно используемых имен; например \\server1\folder\file.ext. Независимо от того, есть ли эта сетевая ссылка в арабском или английском документе, она потребуется для того, чтобы появиться на том же пути. Приведенный ниже рисунок показывает ссылку в арабском документе RightToLeft.

Пример использования элемента Span

Документы с направлением потока справа-налево

Поскольку текст является RightToLeft, все специальные символы, такие как “\”, разделяют текст справа налево. Эти результаты в ссылке показаны в неверном порядке, поэтому, чтобы решить проблему, текст должен быть встраиваемым, сохранить в результате, текст должен быть внедрен, чтобы сохранить отдельное Run, протекающего LeftToRight. Вместо того, чтобы иметь отдельные Run для каждого языка, лучшим способом решить проблему является внедрение наименее часто используемого английского текста в больший по размерам арабский Span.

Это проиллюстрировано на следующем рисунке.

Пример использования элемента Run, встроенного в элемент Span

Снимок экрана XamlPad

Следующий пример демонстрирует использование в документах элементов Run и Span.

<Page
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://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>

Полный пример см. в разделе Пример RunSpan.

Элементы Span

Элемент Span работает как разделительный граничный знак между текстами с разными направлениями потоков. Даже элементы Span с одинаковым направлением полагаются элементами, имеющими различные двунаправленные области, что означает, что элементы Span упорядочены в FlowDirection контейнера, только содержимое в элементе Span следует FlowDirection элемента Span.

Приведенный ниже рисунок показывает направление потока нескольких элементов TextBlock.

Пример FlowDirection в нескольких элементах TextBlock

Текстовые блоки с различными направлениями потоков

В следующем примере показано использование элементов Span и Run для получения результатов, представленных на предыдущем рисунке.

<Page xmlns="https://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>

Полный пример содержится в разделе Пример использования Span.

В элементах TextBlock примера, элементы Span раскладываются согласно FlowDirection их родительских элементов, но текст внутри каждого элемента Span располагается согласно своему собственному FlowDirection. Это применимо для латинского, арабского или любого другого языка.

Добавление xml:lang

Приведенный ниже рисунок показывает другой пример, использующий номера и арифметические выражения, такие как “200.0+21.4=221.4”. Обратите внимание, что установлено только FlowDirection.

Пример чисел, использующих только FlowDirection

Числа с направлением потока справа-налево

Пользователи данного приложения будут разочарованы выходными данными, даже если FlowDirection является правильным, числа не становятся арабскими, хотя должны были стать.

Элементы XAML наследуют свойство XML, вызывающего Обработка xml:lang в XAML (псевдоним Language), определяющий язык каждого элемента. В предыдущем примере, так как не был определен язык для элемента Run или любого из его верхних элементов, использовался язык en-US, являющийся языком по умолчанию. Внутренний алгоритм вида чисел Windows Presentation Foundation (WPF) выбирает числа в соответствующем языке — в данном случае английский. Для того, чтобы правильно отображались арабские цифры необходимо, чтобы был установлен (язык) Обработка xml:lang в XAML.

Приведенный ниже рисунок показывает пример с добавленным свойством языка.

Пример использования атрибута xml:lang

Арабские числа с направлением потока справа-налево

В следующем примере в приложение добавляется (язык) Обработка xml:lang в XAML.

<Page
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://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>

Полный пример см. в разделе Пример LanguageAttribute.

Необходимо помнить, что многие языки имеют различные значения языка в зависимости от целевой области, например, «ar-SA» и «ar-EG» представляют собой два диалекта арабского языка. В предыдущих примерах показано, что необходимо определить язык (xml:lang) и свойства FlowDirection.

FlowDirection с нетекстовыми элементами

FlowDirection определяет не только перетекание текста в текстовом элементе, но также направление потока практически любого другого элемента Пользовательский интерфейс. Приведенный ниже рисунок показывает ToolBar, использующую горизонтальную LinearGradientBrush для отрисовки фона.

Пример ToolBar с градиентом слева направо

Снимок экрана градиента

После установки FlowDirection на RightToLeft, не только кнопки ToolBar располагаются справа налево, но даже LinearGradientBrush перестраивает свои смещения для перетекания справа налево.

Приведенный ниже рисунок показывает перестройку LinearGradientBrush.

Пример ToolBar с градиентом справа налево

Градиент с направлением изменения цвета справа-налево

В следующем примере отрисовывается RightToLeftToolBar. (Чтобы нарисовать его слева направо, удалите атрибут FlowDirection в ToolBar.

<Page
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="https://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 ведет себя не так, как ожидалось. В этом разделе рассматриваются два из этих исключений.

Image

Image представляет элемент управления, который выводит на экран изображение. В XAML его можно использовать со свойством Source, определяющим URI (uniform resource identifier — универсальный код ресурса)Image для вывода на экран.

В отличие от других элементов Пользовательский интерфейс, Image не наследует FlowDirection из контейнера. Однако, если FlowDirection явно задано, равным RightToLeft, то Image выводится на экран зеркально отображенным относительно горизонтали. Это реализуется как удобное средство для разработчиков двунаправленного содержимого; так как в некоторых случаях зеркальное горизонтальное отражение создает требуемый эффект.

Приведенный ниже рисунок показывает зеркально отраженное Image.

Пример зеркально отображенного изображения

Снимок экрана XamlPad

В следующем примере показано, что Image не наследует FlowDirection из StackPanel, содержащей его. Примечание   Чтобы запустить этот пример необходимо, чтобы на диске C:\ находился файл с именем ms_logo.jpg.

<StackPanel 
  xmlns='https://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:\. Необходимо скопировать JPG-файл из файлов проекта на диск C:\ или изменить код для поиска файла внутри проекта. Чтобы это сделать, измените Source="file://c:/ms_logo.jpg" на Source="ms_logo.jpg".

Пути

В дополнение к Image, другим интересным элементом является Path. Объект Path является объектом, который может рисовать последовательности соединенных прямых и кривых. Он ведет себя аналогичным образом что и Image относительно своего FlowDirection; например его RightToLeftFlowDirection является отражением относительно горизонтали его же LeftToRight. Однако, в отличие от Image, Path наследует свое FlowDirection из контейнера и не нуждается в его явном указании.

В следующем примере рисуется простая стрелка, использующая три строки. Первая стрелка наследует направление потока RightToLeft из StackPanel, таким образом, точки начала и конца отсчитываются из корня на правой стороне. Вторая стрелка, имеющая явно заданное RightToLeftFlowDirection, также начинается на правой стороне. Однако, третья стрелка начинается из корня на левой стороне. Дополнительные сведения по рисовании содержатся в LineGeometry и GeometryGroup.

<StackPanel 
  xmlns='https://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

Пути

Image и Path являются двумя примерами того, как Windows Presentation Foundation (WPF) использует FlowDirection. По сравнению с трассировкой элементов Пользовательский интерфейс в конкретном направлении внутри контейнера, FlowDirection может использоваться с такими элементами, как InkPresenter, который отображает рукописные данные на поверхности, LinearGradientBrush, RadialGradientBrush. Всякий раз, когда для содержимого требуется поведение справа налево, имитирующее поведение слева направо, или наоборот, Windows Presentation Foundation (WPF) предоставляет эту возможность.

Подстановка чисел

Исторически Windows поддерживало замену чисел посредством возможности представления различных культурных фигур для одних цифр во время сохранения внутреннего хранения этих цифр, объединенных среди различных местных специфик, например, числа хранятся в хорошо известном шестнадцатеричном формате, 0x40, 0x41, но отображаются на экране согласно выбранному языку.

Это позволяет приложениям вырабатывать цифровые величины без необходимости их конвертации из одного языка в другой, например пользователь может открыть электронную таблицу Microsoft Excel на местном арабском языке Windows и видеть числа, принявшие арабскую форму, однако откройте их в европейской версии Windows и увидите европейское исполнение тех же чисел. Это также необходимо для других символов, таких как разделительные запятые и символ процента, так как они обычно сопровождают числа в одном документе.

Windows Presentation Foundation (WPF) продолжает ту же традицию и добавляет последующую поддержку для этого средства, позволяющего пользовательскому элементу управления контролировать когда и как используется замена. Пока эта возможность сконструирована для любого языка, она особенно полезна в двунаправленном содержимом, в котором вид цифр для специфического языка обычно представляет проблему для разработчиков приложений, потому что приложение может натолкнуться на различные языки и региональные параметры.

Основным свойством, контролирующем число работающих замен в Windows Presentation Foundation (WPF), является свойство зависимости Substitution. Класс NumberSubstitution определяет как отображаются на экране числа в тексте. Он имеет три общих свойств, определяющих его поведение. Ниже приведен краткий обзор каждого из свойств.

CultureSource:

Данное свойство задает, как определяется язык и региональные параметры для чисел. Оно принимает одно из трех значений перечисления NumberCultureSource.

  • Переопределение номера языка и региональных параметров является свойство CultureOverride.

  • Текст номера языка и региональных параметров — это язык и региональные параметры выполнения текста. В разметке это может быть Обработка xml:lang в XAML или его псевдоним Language. Кроме того, он используется по умолчанию для классов, производных от FrameworkContentElement. Такие классы содержат System.Windows.Documents.Paragraph, System.Windows.Documents.Table, System.Windows.Documents.TableCell и так далее.

  • Номер регионального пользователя — это Это свойство используется по умолчанию для всех подклассов FrameworkElement, таких как Page, Window и TextBlock.

CultureOverride:

Свойство CultureOverride используется только если свойство CultureSource задано равным Override, а в противном случае игнорируется. Оно определяет язык и региональные параметры числа. Значение null, значение по умолчанию интерпретируются как en-US.

Substitution:

Это свойство задает тип замены числа на выполнение. Оно принимает одно из следующих значений перечисления NumberSubstitutionMethod.

  • В качестве языка и региональные параметров метод замены определяется на основе свойства NumberFormatInfo.DigitSubstitution языка и региональные параметров числа. Это режим работы по умолчанию.

  • Контекст если язык и региональные параметры числа являются арабскими или персидскими, они указывают, что цифры зависят от контекста.

  • Европейские числа всегда отображаются как европейские цифры.

  • NativeNational числа отображаются с использованием национальных цифр языка и региональных параметров числа, как заданные свойством NumberFormatInfo языка и региональных параметров.

  • Традиционные числа отображаются с использованием традиционных цифр для языка и региональных параметров числа. Для большинства языков и региональных параметров это то же самое, что и NativeNational. Однако, NativeNational для некоторых арабских языков и региональных параметров дают результат в виде латинских цифр, тогда как Traditional дает результат в арабских цифрах для всех арабских языков и региональных параметров.

Что означают эти значения для разработчика двунаправленного содержимого? В большинстве случаев разработчикам может понадобится определить только FlowDirection и язык каждого текстового элемента Пользовательский интерфейс, например Language=”ar-SA” и логика NumberSubstitution заботится об отображении чисел на экране согласно правильным Пользовательский интерфейс. В следующем примере демонстрируется использование арабских и английских чисел в приложении Windows Presentation Foundation (WPF), выполняющемся в арабской версии Windows.

<Page 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="https://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.

Пример отображения на экране арабских и английских чисел

Снимок экрана XamlPad с числами

Полный пример см. в разделе Пример Numbers.

FlowDirection был важен в этом случае, так как если вместо него задать FlowDirection как LeftToRight, то будут появляться европейские цифры. В следующих разделах обсуждаются способы получения единого отображения цифр на экране для всего документа. Если этот пример не выполняется на арабской Windows, все цифры отображаться на экране как европейские цифры.

Определение правил замены

В реальном приложении может потребоваться установить язык программными средствами. Например, требуется установить атрибут Language (xml:lang) таким же как атрибут, используемый системным Пользовательский интерфейс, или возможно требуется изменить язык в зависимости от состояния приложения.

Если требуется внести изменения на основании состояния приложения, проверьте использование других возможностей, предоставляемых Windows Presentation Foundation (WPF).

Сначала установите NumberSubstitution.CultureSource=“Text” компонента приложения. Использование этой настройки гарантирует, что параметры не придут из Пользовательский интерфейс для элементов текста, имеющих значение “User” по умолчанию, таких как TextBlock.

Пример:

<TextBlock

Name="text1" NumberSubstitution.CultureSource="Text">

1234+5679=6913

</TextBlock>

В соответствующем коде C# присвойте свойству язык, например, “ar-SA”.

text1.Language =

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

Если необходимо установить свойство языка на текущий язык Пользовательский интерфейс пользователя, используйте следующий код.

text1.Language =

System.Windows.Markup.XmlLanguage.GetLanguage(

System.Globalization.CultureInfo.CurrentUICulture.IetfLanguageTag);

CurrentCulture предоставляет текущие язык и региональные параметры, используемые текущим потоком во время выполнения.

Окончательный пример XAML должен быть подобен нижеследующему примеру.

<Page x:Class="WindowsApplication.Window1"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://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>

Полный пример см. в разделе Пример Numbers2.

Окончательный пример 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;
            }
        }
    }
}

Полный пример содержится в разделе Пример NumbersCSharp.

На следующем рисунке показано как выглядит окно для любого языка программирования.

Пример отображения на экране арабских чисел

Арабские числа

Использование свойства замены

Способ работы замены числа в Windows Presentation Foundation (WPF) зависит и от языка элемента текста и от его FlowDirection. Если FlowDirection установлено слева направо, то отображаются европейские цифры. Однако, если ему предшествует арабский текст, или оно имеет язык, установленный на «ar» и FlowDirection является RightToLeft, то отображаются арабские цифры.

Тем не менее, в некоторых случаях может потребоваться создание единого приложения, например европейских цифр для всех пользователей. Или арабские цифры в ячейках Table с определенным Style. Просто способ добиться этого заключается в использовании свойства Substitution.

В следующем примере, первый TextBlock не имеет установленного свойства Substitution, поэтому, как и ожидается, алгоритм отображает на экране арабские цифры. Однако, во второй TextBlock, замена задана как европейская, что переопределяет замену по умолчанию для арабских чисел, и на экране отображаются европейские цифры.

<Page x:Class="WindowsApplication.Window1"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://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>

Полный пример см. в разделе Пример Numbers3.