2016-01-19 1 views
1

J'ai donc fait une petite application de test pour tester, si ce texte localisé de liaison à TextBlock fonctionne. J'ai mes doutes, que cela devrait/pourrait être mieux fait et si oui, alors vos recommandations seraient vraiment bien!C# WPF reliant le texte localisé à l'élément

J'ai aussi dans le code XAML commenté TextBlock, que la valeur Bind directement forme resx, mais je ne pouvais pas le faire fonctionner .. Toutes les idées sur la façon dont je pourrais changer ce texte là serait aussi génial! :)

XAML:

<Window x:Class="LocalizationTestWpf.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:LocalizationTestWpf.Resources" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 


    <Grid> 
     <Button x:Name="btnChange" Content="Button" HorizontalAlignment="Left" Margin="206,192,0,0" VerticalAlignment="Top" Width="75" Click="btnChange_Click"/> 
     <!--<TextBlock x:Name="txtDisplay" HorizontalAlignment="Center" Margin="206,138,236,152" TextWrapping="Wrap" Text="{x:Static local:strings.Hello}" VerticalAlignment="Center" TextAlignment="Center" Width="75" Height="29"/>--> 
     <TextBlock x:Name="txtDisplay" HorizontalAlignment="Center" Margin="206,138,236,152" TextWrapping="Wrap" Text="{Binding SayHello}" VerticalAlignment="Center" TextAlignment="Center" Width="75" Height="29"/> 

    </Grid> 
</Window> 

C#:

// http://social.technet.microsoft.com/wiki/contents/articles/22420.binding-to-resources-resx-files-in-xaml.aspx -- how to bind WPF 

     int step = 0; 

     public MainWindow() 
     { 
      Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("et-EE"); 
      // Adds my class (object) as datacontext, so I can bind those values. 
      DataContext = new StringValues(); 
      InitializeComponent(); 
     } 

     private void btnChange_Click(object sender, RoutedEventArgs e) 
     { 
      switch (step) 
      { 
       case 0: 
        // Change language 
        Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR"); 
        // Update DataContext -- Do I need to do it like that? 
        DataContext = new StringValues(); 
        InitializeComponent(); 

        btnChange.Content = "Russian"; 
        step++; 
        break; 
       // Following steps are same as 'case 0', only different language. 
       case 1: 
        Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("ru-RU"); 
        DataContext = new StringValues(); 
        btnChange.Content = "English"; 
        step++; 
        break; 
       case 2: 
        Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US"); 
        DataContext = new StringValues(); 
        btnChange.Content = "Estonian"; 
        step++; 
        break; 
       default: 
        Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("et-EE"); 
        DataContext = new StringValues(); 
        btnChange.Content = "France"; 
        step = 0; 
        break; 
      } 
     } 


    } 

    public class StringValues 
    { 
     public string SayHello 
     { 
      get { return strings.Hello; } 
     } 
    } 

dossier du projet:

Project directory

Comment WPF ressemble à VS (note que textblock est vide avec cette méthode de reliure):

MainWindows.xaml

Exemple fichier RESX:

.resx file

Répondre

2

Une approche possible peut être d'utiliser ResourceDictionary s au lieu de resx.

XAML:

<Window x:Class="BindToResources.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
     <Button x:Name="btnChange" Content="Button" Click="btnChange_Click"/> 
     <TextBlock x:Name="txtDisplay" Text="{DynamicResource Hello}" /> 
    </StackPanel> 
</Window> 

code derrière:

public partial class MainWindow : Window 
{ 
    int step = 0; 

    public MainWindow() 
    { 
     InitializeComponent(); 

     var cultureInfo = CultureInfo.GetCultureInfo("et-EE"); 
     Thread.CurrentThread.CurrentUICulture = cultureInfo; 
     SetLocalization(cultureInfo); 
    } 

    private void btnChange_Click(object sender, RoutedEventArgs e) 
    { 
     CultureInfo cultureInfo; 

     switch (step) 
     { 
      case 0: 
       cultureInfo = CultureInfo.GetCultureInfo("fr-FR"); 
       break; 
      case 1: 
       cultureInfo = CultureInfo.GetCultureInfo("ru-RU"); 
       break; 
      case 2: 
       cultureInfo = CultureInfo.GetCultureInfo("en-US"); 
       break; 
      default: 
       cultureInfo = CultureInfo.GetCultureInfo("et-EE"); 
       break; 
     } 

     Thread.CurrentThread.CurrentUICulture = cultureInfo; 
     SetLocalization(cultureInfo); 
     btnChange.Content = cultureInfo.EnglishName; 
     step = ++step % 4; 
    } 

    private static void SetLocalization(CultureInfo cultureInfo) 
    { 
     var dict = new ResourceDictionary 
     { 
      Source = new Uri(string.Format("pack://application:,,,/Languages/{0}.xaml", cultureInfo.Name)) 
     }; 

     var existingDict = Application.Current.Resources.MergedDictionaries.FirstOrDefault(
      rd => rd.Source.OriginalString.StartsWith("pack://application:,,,/Languages/")); 

     if (existingDict != null) 
     { 
      Application.Current.Resources.MergedDictionaries.Remove(existingDict); 
     } 

     Application.Current.Resources.MergedDictionaries.Add(dict); 
    } 
} 

Vous avez ResourceDictionary classes pour chaque langue (format language_code.xaml):

Solution Explorer

Vous définissez la localisée chaînes dans chaque dictionnaire.

Exemple de russe:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:system="clr-namespace:System;assembly=mscorlib"> 
    <system:String x:Key="Hello">Здравствуйте</system:String> 
</ResourceDictionary> 

Exemple de l'estonien:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:system="clr-namespace:System;assembly=mscorlib"> 
    <system:String x:Key="Hello">Tere</system:String> 
</ResourceDictionary> 

L'idée principale est d'utiliser DynamicResource pour la recherche que vous pouvez voir dans le premier XAML et ajouter le bon ResourceDictionary à Application.Current.Resources pendant l'exécution.

Cela fonctionne pour moi:

End result

+0

J'ai eu à travailler aussi bien. Mais cette méthode donne une erreur dans la page 'MainWindow.xaml' avec' Text = "{DynamicResource Hello}" '(" La ressource "Hello" n'a pas pu être résolue "). Pourquoi cette erreur existe-t-il et existe-t-il un moyen de la réparer? – Taurib

+0

Mon mauvais, ce n'est pas Erreur, c'est Avertissement. – Taurib