W ramach kontynuacji tematu rozpoczętego we wpisie „70-511: Enhancing Usability: Implementacja „Globalizacji” i „Lokalizacji” (teoria)”, zapraszam do zapoznania się z przykładem kodu źródłowego, który będzie
ilustracją do przedstawionej teorii (przykład kodu źródłowego dotyczy implementacji „globalizacji” i „lokalizacji”, ze szczególnym naciskiem na to, jak jest to rozwiązane w lokalizacji dla WPF). W ramach przykładu zostanie pokazane wykorzystanie narzędzia LocBaml.
W przykładzie tym lokalizowane jest proste okno aplikacji WPF. W oknie znajdują się dwie etykiety
z napisami i dwa przyciski zmieniające lokalizację:
<Window x:Class="SampleApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <StackPanel> <TextBlock x:Uid="loc1">Hello World</TextBlock> <TextBlock x:Uid="loc2">Goodbye World</TextBlock> <Button x:Uid="but_PL" Content="PL" Height="23" Name="button_pl" Width="75" Click="button_pl_Click" /> <Button x:Uid="but_EN" Content="EN" Height="23" Name="button_en" Width="75" Click="button_en_Click" /> </StackPanel> </Window>
Oczywiście pierwszym krokiem jest
ustawienie (zgodnie z opisem w poprzednim wpisie)
kultury dla projektu (<UICulture>en-US</UICulture>).
Powoduje to, że po wykonaniu build'u pojawi się nowy plik, np.:
\SampleApp_Localisation\bin\Debug\en-US\SampleApp.resources.dll.
Dodano również [assembly:
NeutralResourcesLanguage("en-US",
UltimateResourceFallbackLocation.Satellite)],
w AssemblyInfo.
Do solution zostało dodane
narzędzie LocBaml, którego kod źródłowy został pobrany ze
strony:
http://msdn.microsoft.com/en-us/library/ms771568%28v=VS.90%29.aspx.
Zwróćmy tutaj uwagę, pobrana została wersja dla .NET 3.5 (tylko
taka jest w chwili pisania artykułu dostępna), dla której
zmieniono docelową platformę na .NET 4.0.
Do projektu zostały dodane dwa
skrypty, które generują plik CSV (generateCSV.cmd) lub assembly
(generateAssembly.cmd) potrzebne do lokalizacji:
skrypt generateCSV.cmd: locbaml /parse en-US\SampleApp.resources.dll skrypt generateAssembly.cmd: md pl-PL locbaml /generate en-US\SampleApp.resources.dll /trans:SampleApp.resources.pl-PL.csv /cul:pl-PL /out:pl-PL
Pierwszy z nich generuje plik
trzeba uruchomić raz po pierwszym buildzie, by wygenerować plik
CSV, który przetłumaczymy, może on wyglądać tak:
plik SampleApp.resources.pl-PL.csv: SampleApp.g.en-US.resources:mainwindow.baml,loc1:System.Windows.Controls.TextBlock.$Content,Text,True,True,,Witaj świecie SampleApp.g.en-US.resources:mainwindow.baml,loc2:System.Windows.Controls.TextBlock.$Content,Text,True,True,,Żegnaj świecie SampleApp.g.en-US.resources:mainwindow.baml,but_PL:System.Windows.Controls.Button.$Content,Button,True,True,, SampleApp.g.en-US.resources:mainwindow.baml,but_PL:System.Windows.Controls.ContentControl.Content,Button,True,True,,PL SampleApp.g.en-US.resources:mainwindow.baml,but_PL:System.Windows.FrameworkElement.Height,None,False,True,,23 SampleApp.g.en-US.resources:mainwindow.baml,but_PL:System.Windows.FrameworkElement.Width,None,False,True,,75 SampleApp.g.en-US.resources:mainwindow.baml,but_EN:System.Windows.Controls.Button.$Content,Button,True,True,, SampleApp.g.en-US.resources:mainwindow.baml,but_EN:System.Windows.Controls.ContentControl.Content,Button,True,True,,EN SampleApp.g.en-US.resources:mainwindow.baml,but_EN:System.Windows.FrameworkElement.Height,None,False,True,,23 SampleApp.g.en-US.resources:mainwindow.baml,but_EN:System.Windows.FrameworkElement.Width,None,False,True,,75
Drugi ze skryptów wykonywany jest
automatycznie w kroku „post-build step”.
Warto jeszcze zwrócić uwagę na
kod obsługi przycisków i funkcję CloseAllWindowsReloadMain
zaczerpniętą z przykładów dostępnych w projekcie
„WPF Localization Guidance” (codeplex).
private void button_pl_Click( object sender, RoutedEventArgs e ) { CultureInfo ci = new CultureInfo( "pl-PL" ); System.Threading.Thread.CurrentThread.CurrentCulture = ci; System.Threading.Thread.CurrentThread.CurrentUICulture = ci; CloseAllWindowsReloadMain(); } private void button_en_Click( object sender, RoutedEventArgs e ) { CultureInfo ci = new CultureInfo( "en-US" ); System.Threading.Thread.CurrentThread.CurrentCulture = ci; System.Threading.Thread.CurrentThread.CurrentUICulture = ci; CloseAllWindowsReloadMain(); } private void CloseAllWindowsReloadMain() { Window oldForm = App.Current.Windows[ 0 ]; Type mainWinType = App.Current.Windows[ 0 ].GetType(); Window mainForm = Assembly.GetExecutingAssembly().CreateInstance( mainWinType.FullName ) as Window; mainForm.Top = oldForm.Top; mainForm.Left = oldForm.Left; mainForm.Show(); // close all windows and reload the startup form foreach ( Window win in App.Current.Windows ) { if ( mainForm == win ) // skip our newly loaded form continue; win.Close(); } }
Zapraszam do pobrania całego kodu
źródłowego dla tego przykładu:
Brak komentarzy:
Prześlij komentarz