Si può consigliare un buon modo per implementare un sistema multilingue per un'app WPF? Il metodo che sto usando adesso include XML, classi e un'estensione xaml. Funziona bene nella maggior parte dei casi, ma quando devo trattare con etichette dinamiche o testo dinamico in generale richiede uno sforzo extra. Vorrei lasciare che il programmatore lavorasse solo nel problema principale e ha dimenticato i problemi del lang.Multilingua in WPF
risposta
Sto usando il WPF Localization Extension. È un modo davvero semplice per localizzare qualsiasi tipo di DependencyProperty
su DependencyObject
s.
- è in un vero e proprio stato stabile
- supporta-come legare stile di scrittura come
Text = {LocText ResAssembly:ResFile:ResKey}
- opere con il meccanismo RESX-fallback (ad esempio it-it -> it -> cultura indipendente)
- supporta la forzatura della cultura (es"Questo deve essere inglese tutto il tempo")
- opere con normali proprietà di dipendenza
- opere con modelli di controllo
- possono essere utilizzati in XAML (davvero: P) senza alcun namespace aggiuntivi
- possono essere utilizzati in codice dietro per associare valori localizzati a controlli dinamici
- strumenti
INotifyPropertyChanged
per uso avanzato - supporta la formattazione di stringhe ad es.
"this is the '{0}' value"
- supporta i valori prefisso e suffisso (attualmente con
LocText
estensione) - è in uso nei sistemi produttivi (come il mio prodotto di pubbliche relazioni)
- commutazione della lingua per runtime colpisce NO timeslice
- può essere utilizzato con qualsiasi file di risorse (
.resx
) in tutte le assemblee (anche la dinamica caricata uno in fase di esecuzione) - non ha bisogno di alcun processo di inizializzazione (come "chiamata xyz per registrare un dizionario Localizzare speciale") .210
- è disponibile in fase di progettazione (MS Expression Blend, MS Visual Studio 2008 (Normale e SP1)
- cambio della lingua scelta è possibile in fase di progettazione
- può localizzare qualsiasi tipo di tipo di dati, fino a quando un convertitore (
TypeConverter
) perché esiste (estendeLocalizeExtension
) - ha un supporto incorporato per
Text
, superioreText
, inferioriText
,Image
s,Brush
es,Double
eThickness
- non influisce alcun perdite di memoria
- lascia intatto l'immobile
- da da utilizzare come
IFormatProvider
(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 sul
Thread.CurrentCulture
oThread.CurrentUICulture
(può essere modificato facilmente)
procedere come segue:
1) Mettere tutti String
frammenti 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) Fai copie per ogni lingua e li (tradotto) aggiungere 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 le stringhe sarà utilizzato per sostituire le parti di testo nel codice.
3a) utilizzare 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) caricare la risorsa dal codice (usare solo questo codice se non lo fai desidera impostare tramite XAML
):
void PageLoad()
{
string str = FindResource("All_Vehicles").ToString();
}
4) Passa alla 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);
}
Ama il tuo suggerimento. Cose da aggiungere: penso che possiamo rendere l'applicazione commutabile in runtime usando '{StaticResource resKey}' –
In realtà, basta specificare {Risorsa risorse dinamiche} ovunque si utilizzino le risorse, quindi in qualsiasi momento al runtime, chiamare SelectCulture (cultura) metodo sopra e aggiornerà tutte le tue stringhe alla nuova cultura in modo dinamico. Invece di: string str = FindResource ("All_Vehicles"). ToString(); Usa: Application.Current.Resources ["All_Vehicles"] come stringa – Curtis
C'è un modo per cambiarlo durante il tempo di esecuzione? – albatross
Josh Smith ha scritto un tutorial approfondito sul suo metodo preferito per questo: Creating an Internationalized Wizard in WPF.
Potrebbe puntare a una grande riprogettazione (è un MVVM solution), ma l'utilizzo di MVVM sembra valere la pena anche per altri motivi.
Usando questo articolo ho è riuscito a utilizzare facilmente i file di risorse per gestire le finestre WPF multilingue. http://www.codeproject.com/KB/WPF/WPF_Resx_Localization.aspx Si dovrebbe dare un controllo perché è davvero semplice ed efficace.
nessuna documentazione o tutorial su come utilizzare questo? –
è ora disponibile una documentazione http://wpflocalizeextension.codeplex.com/documentation – SeriousM