2010-02-16 14 views
7

Ultimamente stavo scavando nella localizzazione con .NET. In sostanza, ho imparato come personalizzare un modulo (utilizzando la proprietà Language e Localizable) e quindi modificare la cultura di conseguenza.Localizzazione .NET; Lingua di fallback quando si utilizza ResourceManager

Tuttavia, ho scoperto che durante la migrazione delle mie stringhe inglesi codificate in modo rigido nei file di risorse generate automaticamente e utilizzare .GetString ("Chiave") - beh, diciamo solo che non era felice: P.

Ho deciso di creare un set separato di file resx dedicato esclusivamente alle traduzioni di stringhe codificate. Hanno seguito la convenzione/requisito di [nome]. [Codice cultura] .resx. Ne ho fatti di questi per ogni lingua rilevante; per esempio. appstrings.de.resx (per tedesco) e appstrings.resx (come base di riferimento invariata).

Per utilizzare queste nuove risorse, ho creato un 'istanza di ResourceManager e Resource Set

Dim resManager As New ResourceManager("LanguageTest.appstrings", Assembly.GetExecutingAssembly) 
Dim resSet As ResourceSet = resManager.GetResourceSet(My.Application.UICulture, True, True) 

La lingua dell'interfaccia utente corrente è stato fissato (ad esempio, per tedesco) utilizzando

My.Application.ChangeUICulture("de") 

Edizione originale

A meno che t Il parametro resSet.GetString ("Chiave") è definito esplicitamente nello appstrings.de.resx, restituirà una stringa vuota. Esiste comunque la possibilità di effettuare il fallback su appstrings.resx (dove "Key" esiste), che presumo sarebbe la linea di base predefinita?

Aggiornamento

Rhapsody ha fatto un suggerimento di sotto, mentre la punta vero e proprio non ha funzionato, lo ha fatto in realtà scintilla un punto interessante, utilizzando resManager.GetString ("chiave") in contrapposizione a resSet .GetString ("chiave"). Questo sembra funzionare senza pecche finora. Cioè, i valori presenti nel file di lingua specializzato vengono restituiti, mentre i valori "mancanti" ricadono nella cultura predefinita quando vi si accede da una singola chiave.

successiva emissione

La questione unica rimasta sarebbe se l'impatto sulle prestazioni di utilizzare ResourceManger al contrario di un ResourceSet cache sarà che dannoso?

risposta

2

Prova

Public Function GetString(ByVal Name As String) As String 
    Return My.Resources.Strings.ResourceManager.GetString(Name) 
End Function 

Dove Strings è il nome dei file resx nel progetto. Questo restituirà automaticamente il valore di base quando non è disponibile per la cultura corrente.

È un esempio semplice, si potrebbe desiderare di renderlo più infallibile.

+1

Sfortunatamente le risorse 'appstrings' non erano presenti nello spazio dei nomi My.Resources. Comunque la tua soluzione di codice solleva un punto interessante (vedi domanda aggiornata) :). –

0

una volta ho creato un'applicazione web che aveva en-US come lingua fallback, ma hanno altri più specifici, come .de in base alle impostazioni del browser degli utenti web

Fondamentalmente a farlo funzionare ho impostato il codice XML nel web.config

<globalization uiCulture="auto" culture="auto" requestEncoding="utf-8" responseEncoding="utf-8"/> 

Da lì ho usato il ResourceManager statica interna dal file con estensione cs che è fornito con la lingua di default, ad esempio,

Resources.<ResourceFileName>.ItemSearchNoResultsErrorText 

e nei file aspx:

<%$ Resources:<ResourceFileName>, TimeSelect %> 

Da quanto ho capito, allora è significativo in cui il file con estensione cs, che contiene la vita di classe ResourceManager, è dietro il file di lingua .de o linguaggio di fallback? Dal momento che si compila come un satellite separato, dipende da dove viene compilata la classe .cs e da quale satellite è parte.

Come regola Ho sempre avuto la classe ResourceManager come codice dietro sulla lingua en-US, perché questo è quello che voglio utilizzare come lingua di fallback se quelle più specifiche non si trovano

Utilizzando questa configurazione non ho mai avuto un valore vuoto, è sempre stato usato il linguaggio fallback, anche se ho scambiato gli assembly satellite in fase di runtime.

+0

Ho letto comunque che l'utilizzo dello spazio dei nomi Risorse è costoso (in termini di prestazioni generali). Ho letto che è meglio creare una risorsa separata impostata per mettere in cache le stringhe, migliorando così le prestazioni. Rhapsody è sulla buona strada con la sua risposta. È solo un ultimo dettaglio che deve essere risolto (vedi il commento a quella risposta). –

4

si può provare a dichiarare una cultura di default per l'applicazione come di seguito

[assembly: NeutralResourcesLanguageAttribute("en-US", UltimateResourceFallbackLocation.Satellite)] 

Questo codice dichiara che la vostra cultura di default è en-US. Nel tuo esempio, se la cultura corrente è "de-DE", cerca la risorsa in "de-DE", quindi cerca la cultura "de" principale e così via e Ultimatly passa al file di risorse cultura definita (en-US) . see MSDN per strategie di fallback di resourceManage. Il codice sopra riportato va normalmente in assenblyInfo.cs. Il secondo parametro indica al gestore risorse dove si trovano le risorse nell'assembly principale o satellite.

Sfortunatamente in questa soluzione è necessario utilizzare un nome di cultura, non il nome del file di risorse. tuttavia potresti estendere RM per utilizzare una risorsa specifica per nome file, ma è più semplice scegliere una cultura predefinita e rinominare il tuo file di risorse in quella cultura e avere la soluzione pronta all'uso.

Problemi correlati