Pattern per la localizzazione delle applicazioni WinForm, ASP.NET e WPF

Localization of .NET applicationsQuando si sviluppa un’applicazione che potrebbe essere usata in diverse parti del mondo, occorre prevedere una localizzazione dell’interfaccia. Se tratta quindi di mostrare componenti, messaggi e altre parti del programma nella giusta lingua. Certo, ci sono molti altri problemi da affrontare quando si parla di localizzazione, ma l’interfaccia e’ quello che, a mio avviso, tra tutti richiede il maggior tempo per gestito.

Non esiste un metodo universalmente riconosciuto e usato per fare tutto questo in .NET, anche se ci sono strumenti e pattern più o meno complessi il cui uso e’ pertinente a determinate situazioni.

WINFORM – LA VIA FACILE

L’articolo MSDN relativo e’ questo: Walkthrough: Localizing Windows Forms.
In pratica, se occorre localizzale label, menu e altri elementi di un form, il compito e’ semplice e viene fatto tutto grazie all’editor di Visual Studio. Si disegna la propria finestra e si impostano tutte le etichette standard, quelle che devono apparire di default. Si passano poi a definire le traduzioni per un certo linguaggio impostando la proprieta’ Language del form e modificando le etichette dei controlli. Il sistema, in fase di esecuzione dell’applicativo, provvedera’ a selezionare uno dei linguaggi personalizzati basandosi su quello del sistema. Se invece si vuole impostare una lingua, occorre agire su Thread.CurrentThread.CurrentUICulture. Tutto funziona grazie ad un file di risorse, creato automaticamente dall’editor, per ogni finestra  / controllo che localizzo con questo medoto.
Approccio molto simile per ottenere delle stringhe localizzate, utili per MessageBox e altre informazioni da mostrare all’utente. Si crea un file delle risorse (quello di default e quelli specifici per le lingue gestite), si inseriscono in questi file le coppie chiave/valore (nel valore c’e’ il testo tradotto) e poi da codice si usa un ResourceManager, legato al file delle risorse creato, per ottenere i valori delle chiavi richieste in base alla cultura corrente.
Pro di questo metodo l’estrema facilita’ di implementazione e la scrittura di poco codice, contro il fatto che occorre ricompilare e ridistribuire il progetto ad ogni cambiamento dei testi e che le risorse localizzate non risiedono in un unico punto ma sono sparse all’interno dell’applicazione.

Per localizzare anche i componenti che mostrano date e valute, occorre agire su Thread.CurrentThread.CurrentCulture, seguendo quanto scritto in How to: Set the Culture and UI Culture for Windows Forms Globalization.

ASP.NET – RESOURCE PROVIDER PER TUTTI

ASP.NET 2.0 Localization Features: A Fresh Approach to Localizing Web Applications: l’articolo di riferimento da leggere per la localizzazione delle applicazioni un ASP.NET 2.0
Introduction to Localization in ASP.NET 2.0: questo articolo, che attinge a larga mano dal precedente, espone alcuni concetti di base della localizzazione in ASP.NET 2.0, parlando di assembly delle risorse (gli stessi utilizzati in maniera trasparente nell’approccio WinForm precedente), spiega come impostare una pagina in base alla lingua predefinita nel browser dell’utente, fa una panoramica su risorse globali (GetGlobalResourceObject) e risorse locali (GetLocalResourceObject), su come funziona il Resource Fallback, su come assegnare via markup code il testo dei controlli nella pagina asp grazie alle Implicit ed Explicit Resource Expressions.

Punti di debolezza di questi approcci, il fatto che i resource file sono gestiti automaticamente e non si possono condividere, ad esempio, con una versione WinForm della stessa applicazione. Inoltre, come il precedente, ogni cambiamento delle risorse necessita di una ricompilazione e ridistribuzione di parti dell’applicazione.

WINFORM e ASP.NET – GESTIONI PIU’ COMPLESSE

Se l’uso dei file di risorse dell’applicazione non e’ quello che si vuole usare, perche’ magari le traduzioni devono risiedere su un database oppure devono essere distribuite attraverso file xml, se occorre tenere in considerazione l’orientamento del testo della cultura scelta nel disegno del form, se per ognuna occorre anche ridimensionare label e textbox o cambiare immagini e colori, allora le due precedenti “via facili” non sono piu’ sufficienti.

Fortunatamente ASP.NET offre la possibilita’ di definire dei custom resource provider, in grado di accedere alle risorse fuori dall’ambito dell’App_GlobalResources e dell’App_LocalResources. Ad esempio alimentandosi da un database o da un assembly esterno.
Extending the ASP.NET 2.0 Resource-Provider Model mostra come implementare un proprio Database Resource Provider, prestando attenzione a fattori come il resource fallback, il caching, l’accesso multithreading al database e l’impostazione dellla sezione <globalization> del Web.config per usare il proprio resource provider. Segue anche una trattazione per attingere i dati da un assembly esterno. per la lettura dei dati.
Creating a Data Driven ASP.NET Localization Resource Provider and Editor: seguendo l’approccio del precedente articolo, viene costruito un Database Resource Provider ed un editor ASP.NET per modificare agevolmente le risorse. Trattazione esplicita e molti esempi di codice, con la definizione completa  e puntuale di tutto quello che va implementato.

Per quanto rigurda le applicazioni WinForm invece non esiste un approccio standard alla risoluzione di questi problemi, e occorre fare molte cose via codice esplicito, creandosi il proprio dizionario dove contenere le traduzioni localizzate, modificare attraverso il codice label, titoli, posizioni e quant’altro occorre considerare per la cultura corrente.
Oppure passara a WPF.

LOCALIZZAZIONE IN WINDOWS PRESENTATION FOUNDATION (WPF)

Il discorso si fa ampio e complesso perchè WPF e’ pensato per la localizzazione piu’ totale, quindi sono molte le possibilità offerte, ognuna con i suoi pro e contro e con determinati aspetti tenuti in considerazione: verso di scrittura, (sinistra-destra oppure destra-sinistra) grandezza dei controlli che si devono o non devono autoridimensionare a secondo del testo in essi contenuto.
cultura di fallback, quella cioe’ da usare se non esiste la specifica cultura impostata nel sistema operativo in uso, l’uso del tag Xml:lang, possibilita’ di modificare a runtime la cultura usata. I risultati, comunque, sono abbastanza semplici da ottenere.

Un po’ di teoria:
WPF Globalization and Localization Overview: best practices nel disegno di interfacce multilinguaggio, definizione di un language-neutral main assembly per il progetto e dei language-dependent satellite resource assembly dove inserire le proprie risorse localizzate. Utilizzo del tag Uid negli elementi del file xaml.
Globalization for the Windows Presentation Foundation: Aggiunge, rispetto al precedente, qualche raccomandazione per l’uso di ClickOnce

Ed alcuni esempi hands-on:
Globalization and Localization Samples: una serie di esempi tratti dalla MSDN che fanno vedere varie tecniche di localizzazione focalizzate su piccole e semplici tematiche.
WPF Multi-Lingual at Runtime: localizzazione delle stringhe di un xaml mediante file xml. Soluzione semplice per situazioni semplici, la lettura del primo commento “My favorite approach” suggerisce come alleggerire un po’ il file xml e lo xaml.
Localizing WPF Applications using Locbaml: in realta’ tre articoli in uno, questo esauriente tutorial si approccia alla locazzazione di un’applicazione WPF seguendo tre diverse strade: la prima utilizza il Resources.resx, la classe Properties.Resources e un po’ di sano binding nello xaml. La seconda invece crea delle satellite dll, usa gli Uid degli elementi dello xaml, usa MSBuild.exe e LocBaml.exe e altri concetti. La terza e’ un’ulteriore raffinazione della seconda tecnica. Personalmente ho trovato il primo approccio semplice e abbastanza utile. Inoltre, non ho neanche dovuto ridefinire il ResXFileCodeGenerator grazie al commento “Found I didn’t need the custom code generator“, ho notato che l’editor xaml di Visual Studio 2008 offre pieno supporto a questo approccio, senza i problemi che ha avuto l’autore. Occorre pero’ correggere il contenuto del tag <Button> sostituendo la stringa
“{x:Static properties:Resources.MainButtonText}”
con la stringa
<TextBlock TextAlignment=”Center” Text=”{x:Static properties:Resources.MainButtonText}”/>

Real-Time Multilingual WPF Demo: un progetto che si appoggia sul servizio di traduzione online offerto da Google per ottenere on-the-fly le stringhe da tradurre in base ad un linguaggio di origine e uno di destinazione impostabili a runtime. Prevede anche l’uso di una custom markup extension per rendere più facile da scrivere il codice xaml.

Ci sono poi delle librerie che permettono di usare altri modi di gestire la localizzazione di stringhe e immagini, senza dover usare LocBaml, file di risorse ed altro.
WPF Localization by Tomer Shamam:
i dizionari usati per le traduzioni possono essere creati in maniera disaccoppiata dalla forma di persistenza, potendo quindi usare xml, database o altro, prevede l’utilizzo di parametri bindabili nelle stringe localizzate ed e’
inclusa anche una markup language extension per rendere piu’ elegante e semplice la scrittura dello xaml. Permette di bindare qualunque
attributo dei controlli, ad esempio la larghezza di una label, nel codice viene mostrato come usare diverse immagini a secondo della lingua usata. Gestiti i valori di default, update automatico delle proprieta’ localizzate dei controlli a runtime, supportati i DataTemplate ma non la localizzazione dei ContextMenu.
WPF LocalizeExtension by SeriousM: utilizza file di risorse (.resx) per memorizzare i contenuti da localizzare, senza passare quindi per le satellite dll e supportando il .resx-fallback mechanism (en-us -> en -> independent culture). Custom markup extension per la scrittura semplificata dello XAML, possibilita’ di visualizzare un certo linguaggio a design-time, update automatico delle proprieta’ localizzate dei controlli a runtime, gestione del binding anche nel code behind, la chiave per collegare la risorsa localizzata e’ composta da assembly:nomerisorsaresx:chiave. Libreria potente, una scelta obbligata se volete far uso dei file resx.
WPF application localization kit by Taggersoft: terza soluzione del gruppo, c’e’ un buon tutorial che ne spiega l’utilizzo, ma le localizzazioni devono risiedere necessariamente su di uno XAML based ResourceDictionary e non e’ cosi’ potente come le precedenti.

Personalmente per le mie applicazioni WPF utilizzero’ la libreria di SeriosM, con qualche piccola modifica, in modo da avere le traduzioni residenti sul db e poterle cosi’ gestire in maniera molto flessibile.

CONCLUSIONI

La trattazione dell’argomento non puo’ essere esaustiva, dato che nuovi pattern possono essere implimentati a secondo dei propri bisogni. Voglio comunque segnalare alcuni strumenti che possono aiutare in questo compito, come ad esempio RGreatEx, un plugin a pagamento per Visual Studio che identifica le stringhe di testo e ne fa il rafactoring in file di risorse, controlla inoltre se sono state localizzate per tutte le lingue, traduce automaticamente una stringa appoggiandosi su servizi online e molto altro. Oppure un breve snippet di codice per accedere ad una risorsa in una satellite dll: How to: Access Resources in Satellite DLLs.

2 Comments

  1. Pingback: Spunti per gestire la localizzazione di applicazioni | ObondO Labs

Leave a Reply