2016-08-24 1 views
3

J'utilise WPF Localisation Extension dans mon programme. Pour réduire le nombre de ressources similaires (comme "Longueur en mètres", "Longueur en Kilomètres", etc.), je souhaite utiliser des espaces réservés et les définir en code XAML.Utilisation d'espaces réservés dans XAML pour l'extension de localisation WPF

Je pensais à quelque chose comme ça

La valeur de la ressource "UI_Length"

Length in {0} 

En CodeBehind cela est assez facile avec String.Format

String.Format(
     LocalizeDictionary.Instance.GetLocalizedObject("UI_Length", null, LocalizeDictionary.Instance.Culture).ToString(), 
     "Meters"); 

Mais comment -je ajouter une autre chaîne ou même une autre entrée de ressource dans XAML?

<Label x:Name="Label" Content="{lex:LocText Key=UI_Length}, Meters" HorizontalAlignment="Left" VerticalAlignment="Top"/> 

Selon Binding placeholder from resource file in WPF il semble être possible, mais je ne suis pas en mesure de le faire fonctionner pour une étiquette

[Mise à jour]

J'ai réussi à ajouter deux valeurs de ressources. L'astuce consistait à ajouter un TextBlock dans Label.Content. see Link

 <Label Grid.Row="1"> 
      <Label.Content> 
       <TextBlock> 
        <TextBlock.Text> 
         <MultiBinding StringFormat="{}{0} [{1}]"> 
          <Binding Source="{lex:LocText Key=UI_Length}" /> 
          <Binding Source="{lex:LocText Key=UI_MeterShort}" /> 
         </MultiBinding> 
        </TextBlock.Text> 
       </TextBlock> 
      </Label.Content> 
     </Label> 

Mais j'ai toujours un problème ici. Au démarrage cela fonctionne bien, mais lorsque je tente de changer la langue avec

LocalizeDictionary.Instance.Culture = new CultureInfo("de-DE"); 

je reçois un « Binding ne peut pas être changé après qu'il a été utilisé. » Erreur. Existe-t-il une manière similaire d'utiliser plusieurs valeurs Ressource et de toujours pouvoir changer de langue pendant l'exécution?

[Mise à jour 2]

J'ai essayé la suggestion de Liero mais ont encore un problème ici.

Dans ma vue principale, je définis le DataContext à MainViewModel. La machine virtuelle possède une instance de LocalizedTexts. Après avoir changé la langue dans le ViewModel j'appelle le RaisePropertiesChanged() mais je n'obtiens aucune sortie.

TextBlock est lié aux LengthInMeters

<TextBlock Text="{Binding LocalizedTexsts.LengthInMeters}" /> 

J'appelle le RaisePorpertyChanged après avoir changé la langue:

public void ChangeLanguage(string culture) 
    { 
     LocalizeDictionary.Instance.Culture = new CultureInfo(culture); 
     _localizedTexts.RaisePropertyChanged(); 
    } 

LengthInMeters ressemble à ceci:

public string LengthInMeters 
{ 
    get 
    { 
     return String.Format(
        LocalizeDictionary.Instance.GetLocalizedObject(
         "UI_Length", null, 
         LocalizeDictionary.Instance.Culture).ToString(), 
        LocalizeDictionary.Instance.GetLocalizedObject(
         "UI_Meters", null, 
         LocalizeDictionary.Instance.Culture).ToString() 
       ); 
    } 
} 

Mais le TextBlock reste vide.

Répondre

3

D'abord, vous pouvez raccourcir la liaison comme ceci:

<TextBlock Text="{Binding Source={lex:LocText Key=UI_MeterShort}, 
          StringFormat={lex:LocText Key=UI_Length}}" /> 

Deuxièmement, si vous souhaitez mettre à jour la liaison, en cas de changement de langue, alors vous devez trouver le TextBlock dans codebehind et mettre à jour la liaison manuellement en utilisant la méthode BindingExpression.UpdateTarget(). Mais c'est étrange, n'est-ce pas?

Vous pouvez également actualiser la totalité de la fenêtre en supprimant tout son contenu et en en créant de nouveaux. Je veux dire quelque chose comme enlever un UserControl de la fenêtre et créer un nouveau UserControl. Cependant, les deux solutions sont bizarres, car il s'agit simplement de problèmes de contournement causés par une mauvaise utilisation des liaisons dans WPF. Laissez-moi vous suggérer une meilleure approche.

public class LocalizedTexts: INotifyPropertyChanged 
{ 
    public event PropertyChanged; 


    public LengthInMeters { get { return String.Format(...); } } 

    public LengthInKilometers {get { return String.Format(...); } } 


    public void RaisePropertiesChanged() 
    { 
     foreach (var property in this.GetType().GetProperties()) 
     { 
     PropertyChanged(this, new PropertyChangedEventArgs(property.Name)) 
     } 
    } 
} 

vous pouvez maintenant à LocalizedTexts et DataBind lors du changement de langue, il suffit d'appeler RaisePropertiesChanged().

USAGES:

<Application.Resources> 
    <l:LocalizedTexts x:Key="LocalizedTexts" /> 
</Application.Resources> 

<TextBlock Text="{Binding LengthInMeters, Source={StaticResource LocalizedTexts}}" /> 


<!-- instead of using StaticResource, you can add l:LocalizedTexts as a property to your viewmodel --> 
<TextBlock Text="{Binding LocalizedTexts.LengthInMeters}" /> 
+0

J'ai essayé votre approche proposée mais qui ont encore un problème ici. Ce que j'ai fait est: Dans mon MainView j'ai placé le DataContext à MainViewModel. La machine virtuelle possède une instance de LocalizedTexts. Après avoir changé la langue dans le ViewModel j'appelle le RaisePropertiesChanged() mais je n'obtiens aucune sortie. => s'il vous plaît jeter un oeil à la mise à jour 2 pour plus de détails. – 4pinsGigabit