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


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

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

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

FlowDirection

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

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

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

Graphic that illustrates the different flow directions.

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

В следующем примере демонстрируется задание параметра 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, нужно явным образом добавить изменение направления, как у второго свойства TextBlock из примера выше, для которого значение меняется на LeftToRight. Если свойство FlowDirection не определяется, то применяется значение по умолчанию LeftToRight.

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

Graphic that illustrates the explicit flow direction change.

FlowDocument

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

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

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

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

Graphic that illustrates using the Span element.

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

На следующем рисунке показано использование элемента Run, внедренного в элемент Span:

Graphic that illustrates the Run element embedded in a Span element.

В следующем примере показано использование элементов 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 обеспечивается соответствие значению свойства FlowDirection этого конкретного элемента Span.

На следующем рисунке демонстрируется направление потока для нескольких элементов TextBlock.

Graphic that illustrates text blocks with different flow directions.

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

Graphic that displays numbers using only FlowDirection.

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

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

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

Graphic that illustrates Arabic numbers that flow from right to left.

В следующем примере параметр 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" и "ar-EG" представляют собой два диалекта арабского языка. Предыдущий пример показывает, что необходимо определить оба значения xml:lang и FlowDirection.

Направление потока применительно к нетекстовым элементам

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

Graphic that shows a toolbar with a left to right gradient.

После задания для FlowDirection значения RightToLeft не только изменяется порядок размещения кнопок ToolBar в направлении справа налево, но и элемент LinearGradientBrush изменяет свои смещения, которые теперь ориентированы в направлении справа налево.

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

Graphic that shows a toolbar with a right to left gradient.

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

<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 не работает так, как можно было бы ожидать. В этом разделе рассматриваются два таких исключения.

Изображение

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

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

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

Graphic that illustrates a flipped image.

В следующем примере демонстрируется, что Image не наследует свойство FlowDirection из элемента StackPanel, в котором он содержится.

Примечание.

Для запуска этого примера необходимо иметь файл с именем ms_logo.jpg на диске C:\.

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

Paths

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

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

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

Graphic that illustrates arrows drawn using the Path element.

Path Ниже Image приведены два примера использования WPFFlowDirection. Помимо размещения элементов пользовательского интерфейса в определенном направлении в контейнере, 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.

  • Override (переопределение): региональные параметры числа соответствуют свойству CultureOverride.

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

  • User (пользователь). Региональный стандарт для чисел определяется по региональному стандарту текущего потока. Это свойство используется по умолчанию для всех подклассов, таких как FrameworkElement, Page, Window и TextBlock.

CultureOverride.

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

Substitution.

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

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

  • Context: если языком и региональными параметрами числа является "Арабский" или "Персидский", указывает, что цифровые величины зависят от контекста.

  • European: числа всегда отображаются как европейские числовые величины.

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

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

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

<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, когда отображаются арабские и английские числовые величины:

Graphic that shows Arabic and English numbers.

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

Определение правил подстановки

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

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

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

Например:

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

В соответствующем коде C# нужно задать для свойства Language, например, значение "ar-SA".

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

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

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

На следующем рисунке показано, как выглядит окно для каждого языка программирования при отображении арабских чисел:

Graphic that displays Arabic numbers.

Использование свойства подстановки

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

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

В следующем примере для первого элемента TextBlock не задано свойство Substitution, поэтому в соответствии с имеющимся алгоритмом отображаются арабские числа, как это и должно быть. А для второго текстового блока 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>