Localization of text including subscripts and embedded images in WPF

I have a small WPF application that I'm working on localization. I read several documents, but I did not find a good source of information on working with "rich" content - for example:

I have a ui element (TextBlock) that contains a combination of text with formatting, inline images and characters. I want to localize this element. I believe that localizing this element in a way that is natural in another language so that the position of the formulas / characters should shift relative to the surrounding text - and that the best formatting of the text may differ slightly in other languages, as well.

I am looking for suggestions, resources and / or approaches for localizing “rich” content (content that mixes text, formatting and inline ui elements) in XAML / WPF. Given the emphasis on composition and the rich user interface in WPF, I was surprised to find no information about the script above - what am I missing?

I thought about storing XAML in a resource file, and then parsed it at runtime to include in the user interface and creating a view / usercontrol that changes to the locale, but I don't see any mention of these approaches (which makes me wonder if I'm on the “wrong track”), and I hope someone has the experience or information to share?

Thanks!

+3
3

StaticResource , . , StaticResource, DynamicResource :

<Window ...>
  <Window.Resources>

    <Span x:Key="Whatever">
      <Bold>Hello</Bold> there<LineBreak/>
      A green circle:
      <InlineUIContainer>
        <Ellipse Width="10" Height="10" Fill="Green" />
      </InlineUIContainer>
    </Inline>

  </Window.Resources>

  ...
  <TextBlock>
    <StaticResource ResourceKey="Whatever" />
  </TextBlock>

:

  • Span ResourceDictionary .
  • , - , , , ResourceDictionary application.Resources.MergedDictionaries. WPF.

, , , , , , , dll xaml , :

<ResourceDictionary>
  <Span x:Key="Whatever">
    El círculo rojo
      <InlineUIContainer>
        <Ellipse Width="10" Height="10" Fill="Red" />
      </InlineUIContainer>
    dice <Bold>hola!</Bold>
  </Span>
</ResourceDictionary>

, , , .

ControlTemplates, . ControlTemplates , , . , :

<ResourceDictionary>
  <ControlTempate x:Key="Something" TargetType="ContentControl">
    <StackPanel>
      <TextBlock Text="In English we want the text above the button" />
      <ContentPresenter />
    </StackPanel>
  </ControlTemplate>
</ResourceDictionary>

:

<ContentControl Template="{StaticResource Something}">
  <Button Command="Save">Save File</Button>
</ContentControl>

, :

<ResourceDictionary>
  <ControlTempate x:Key="Something" TargetType="ContentControl">
    <DockPanel>
      <ContentPresenter DockPanel.Dock="Left" />
      <TextBlock Text="En español en el botón a la izquierda del texto" />
        <!-- In spanish the button is to the left of the text -->
    </DockPanel>
  </ControlTemplate>
</ResourceDictionary>

. DependencyProperties (, InlineCollections ..), {DynamicResource}, . , <Span> ResourceDictionary TextBlock, TextBlock ControlTemplate ResourceDictionary.

WPF. .

+2

, :

"Hello, my <b>dear</b> user!"

- :

",  <b></b> !!" 

, , , , . , , (3) .

EDIT. , :

<img src="$current_locale/logo.jpg" />

, , :

<img src="$get_current_locale_or_default_locale_image(logo.jpg)" />
0

Ray Burns StaticResource , , . - T4 "" xaml , CurrentCulture.

base_block.tt. , , - = "" ( , Utf-8 , XamlParser , Utf-8, -, - ).

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".xaml" encoding="Unicode"#>

<UserControl
    xml:lang="<#= this.xml_lang #>"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="basic_styles.xaml" />
                <ResourceDictionary Source="equations.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>

        <WrapPanel Style="{StaticResource description_wrap_panel_style}">

                <TextBlock  x:Name="c_textblock"
                                Style="{StaticResource description_textblock_style}" 
                                AutomationProperties.Name = "<#= this.textblock_automation_name #>">
                        <#= this.textblock_constant_C_contents #>
                </TextBlock>

                <TextBlock  Style="{StaticResource description_textblock_style}"
                                KeyboardNavigation.TabIndex="1">
                        <#= this.hyperlink_textblock_contents #>
                </TextBlock>

                <TextBox    Style="{StaticResource entry_textbox_style}"
                                AutomationProperties.LabeledBy="{Binding ElementName=c_textblock}"
                                KeyboardNavigation.TabIndex="0">
                </TextBox>

        </WrapPanel>

</UserControl>

<#+ 

private string xml_lang = @"";
private string textblock_constant_C_contents = @"";
private string textblock_automation_name = @"";
private string hyperlink_textblock_contents = @"";

#>

base_block.tt include .tt, . en.tt, en.xaml:

<# 

xml_lang = @"en-US";

textblock_constant_C_contents = 
    @"Enter a constant, <Italic>C</Italic>, that satisfies
            <InlineUIContainer Style='{StaticResource image_container_style}'>
                    <Image x:Name='formula_11' Source='{StaticResource equation_11}' Style='{StaticResource image_style}' Tag='3.0'>
                    <Image.Height>
                        <MultiBinding Converter='{StaticResource image_size}'>
                            <Binding Mode='OneWay' ElementName='formula_11' Path='Tag'/>                        
                            <Binding Mode='OneWay' ElementName='c_textblock' Path='FontSize'/>
                        </MultiBinding>
                    </Image.Height>
                </Image>
            </InlineUIContainer>";

textblock_automation_name = @"Enter a Constant, C, that satisfies the following equation: the standard error of the estimate is equal to the constant C over the square root of the sample size";

hyperlink_textblock_contents = @"(<Hyperlink AutomationProperties.Name='More information about the constant C' 
                                        x:Name='c_hyperlink'>more info</Hyperlink>)";

#>

<#@ include file="base_block.tt" #>

- fr.tt → fr.xaml:

<# 

xml_lang = @"fr";

textblock_constant_C_contents = 
    @"Entrez une constante, <Italic>C</Italic>, pour satisfaire
            <InlineUIContainer Style='{StaticResource image_container_style}'>
                    <Image x:Name='formula_11' Source='{StaticResource equation_11}' Style='{StaticResource image_style}' Tag='3.0'>
                    <Image.Height>
                        <MultiBinding Converter='{StaticResource image_size}'>
                            <Binding Mode='OneWay' ElementName='formula_11' Path='Tag'/>                        
                            <Binding Mode='OneWay' ElementName='c_textblock' Path='FontSize'/>
                        </MultiBinding>
                    </Image.Height>
                </Image>
            </InlineUIContainer>";

textblock_automation_name = @"Entrez une constante, C, qui satisfait l'équation suivante: l'erreur-type de l'estimation est égale à la constante C sur la racine carrée de la taille de l'échantillon.";

hyperlink_textblock_contents = @"(<Hyperlink AutomationProperties.Name=""Plus d'informations sur la constante C"">en savoir plus</Hyperlink>)";

#>

<#@ include file="base_block.tt" #>

French creates the following .xaml file:

<UserControl
    xml:lang="fr"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="basic_styles.xaml" />
                <ResourceDictionary Source="equations.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>

        <WrapPanel Style="{StaticResource description_wrap_panel_style}">

                <TextBlock  x:Name="c_textblock"
                            Style="{StaticResource description_textblock_style}" 
                            AutomationProperties.Name = "Entrez une constante, C, qui satisfait l'équation suivante: l'erreur-type de l'estimation est égale à la constante C sur la racine carrée de la taille de l'échantillon.">
                        Entrez une constante, <Italic>C</Italic>, pour satisfaire
                    <InlineUIContainer Style='{StaticResource image_container_style}'>
                            <Image x:Name='formula_11' Source='{StaticResource equation_11}' Style='{StaticResource image_style}' Tag='3.0'>
                            <Image.Height>
                                <MultiBinding Converter='{StaticResource image_size}'>
                                    <Binding Mode='OneWay' ElementName='formula_11' Path='Tag'/>                        
                                    <Binding Mode='OneWay' ElementName='c_textblock' Path='FontSize'/>
                                </MultiBinding>
                            </Image.Height>
                        </Image>
                    </InlineUIContainer>
                </TextBlock>

                <TextBlock  Style="{StaticResource description_textblock_style}"
                            KeyboardNavigation.TabIndex="1">
                        (<Hyperlink AutomationProperties.Name="Plus d'informations sur la constante C">en savoir plus</Hyperlink>)
                </TextBlock>

                <TextBox    Style="{StaticResource entry_textbox_style}"
                            AutomationProperties.LabeledBy="{Binding ElementName=c_textblock}"
                            KeyboardNavigation.TabIndex="0">
                </TextBox>

        </WrapPanel>
</UserControl>

At runtime, I look at CurrentCulture, compare it with the generated xaml files that are available, pass the XamlReader.Load () file, and add the resulting Usercontrol where necessary. A small sample application demonstrating this is available here .

0
source

Source: https://habr.com/ru/post/1721667/


All Articles