Multilingua in WPF [chiuso]
-
03-07-2019 - |
Domanda
Puoi consigliare un buon modo per implementare un sistema multilingue per un'app WPF? Il metodo che sto usando in questo momento prevede XML, classi e un'estensione xaml. Funziona bene nella maggior parte dei casi, ma quando devo occuparmi di etichette dinamiche o di testi dinamici in generale, richiede qualche sforzo in più. Vorrei lasciare che il programmatore lavorasse solo nel problema principale e abbia dimenticato i problemi di lingua.
Soluzione
Sto utilizzando la Estensione di localizzazione WPF . È un modo davvero semplice per localizzare qualsiasi tipo di DependencyProperty
su DependencyObject
s.
- è in uno stato reale stabile
- supporta uno stile di scrittura vincolante come
Text = {LocText ResAssembly: ResFile: ResKey}
- funziona con il meccanismo .resx-fallback (ad es. en-us - > en - > cultura indipendente)
- supporta il forzante culturale (ad es. " questo deve essere sempre inglese ")
- funziona con le normali proprietà di dipendenza
- funziona con i modelli di controllo
- può essere utilizzato in XAML (in realtà: P) senza spazi dei nomi aggiuntivi
- può essere utilizzato nel codice dietro per associare valori localizzati a controlli generati dinamici
- implementa
INotifyPropertyChanged
per uso avanzato - supporta la formattazione di stringhe ad es.
" questo è il valore '{0}' "
- supporta i valori di prefisso e suffisso (attualmente con estensione
LocText
) - è in uso in sistemi produttivi (come il mio prodotto di pubbliche relazioni)
- il passaggio dalla lingua al runtime influisce su NO timeslice
- può essere utilizzato con qualsiasi file di risorse (
.resx
) in tutti gli assembly (anche quello dinamico caricato in fase di runtime) - non ha bisogno di alcun processo di inizializzazione (come " chiama xyz per registrare un dizionario di localizzazione speciale ")
- è disponibile in fase di progettazione (MS Expression Blend, MS Visual Studio 2008 (Normal e SP1)
- è possibile cambiare la lingua scelta in fase di progettazione
- può localizzare qualsiasi tipo di tipo di dati, purché esista un convertitore (
TypeConverter
) (estendeLocalizeExtension
) - ha integrato il supporto per
Text
,Text
,Text
,Image
,Spazzola
es,Double
eThickness
- non influisce su eventuali perdite di memoria
- lascia intatta la proprietà
UID
- offre un
SpecificCulture
da utilizzare comeIFormatProvider
(ad es.(123.20) .ToString (LocalizeDictionary.SpecificCulture) = " 123.20 "
o" 123,20 "
) - offre alcune funzionalità per controllare e ottenere i valori delle risorse nel codice dietro
- non altera la cultura su
Thread.CurrentCulture
oThread.CurrentUICulture
(può essere modificato facilmente)
Altri suggerimenti
Segui questi passaggi:
1) Posiziona tutti i frammenti String
in un file di risorse separato.
Esempio: StringResources.xaml
:
<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">
<!-- String resource that can be localized -->
<system:String x:Key="All_Vehicles">All Vehicles</system:String>
</ResourceDictionary>
2) Crea copie per ogni lingua e aggiungile (tradotte) ai dizionari uniti. Non dimenticare di aggiungere il codice ISO del Paese per semplificare le cose.
Esempio App.xaml
:
<Application x:Class="WpfStringTables.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<ResourceDictionary >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="StringResources.de-DE.xaml" />
<ResourceDictionary Source="StringResources.nl-NL.xaml" />
<ResourceDictionary Source="StringResources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
L'ultimo file di risorse con stringhe verrà utilizzato per sostituire le parti di testo nel codice.
3a) Utilizza le parti di testo dalla tabella String
:
Esempio Window1.xaml
:
<Window x:Class="WpfStringTables.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Button Margin="51,82,108,129" Name="AllVehiclesButton"
Content="{StaticResource All_Vehicles}"/>
</Grid>
</Window>
3b) Carica la risorsa dal codice (utilizza questo codice solo se non desideri impostare tramite XAML
):
void PageLoad()
{
string str = FindResource("All_Vehicles").ToString();
}
4) Passa a una nuova cultura all'avvio dell'applicazione:
Codesnippet da App.xaml.cs
:
public static void SelectCulture(string culture)
{
if (String.IsNullOrEmpty(culture))
return;
//Copy all MergedDictionarys into a auxiliar list.
var dictionaryList = Application.Current.Resources.MergedDictionaries.ToList();
//Search for the specified culture.
string requestedCulture = string.Format("StringResources.{0}.xaml", culture);
var resourceDictionary = dictionaryList.
FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
if (resourceDictionary == null)
{
//If not found, select our default language.
requestedCulture = "StringResources.xaml";
resourceDictionary = dictionaryList.
FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
}
//If we have the requested resource, remove it from the list and place at the end.
//Then this language will be our string table to use.
if (resourceDictionary != null)
{
Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
}
//Inform the threads of the new culture.
Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
}
Josh Smith ha scritto un tutorial approfondito sul suo metodo preferito per questo: Creazione di un Procedura guidata internazionalizzata in WPF .
Potrebbe indirizzarti verso una grande riprogettazione (è una soluzione MVVM ), ma l'utilizzo di MVVM sembra valere la pena anche per altri motivi.
Usando questo articolo sono riuscito a usare facilmente i file di risorse per gestire le finestre WPF multilingue. http://www.codeproject.com/KB/WPF/WPF_Resx_Localization.aspx Dovresti dare un assegno perché è davvero semplice ed efficace.