Silverlight – lokalizacja aplikacji

Nowoczesne aplikacje web’owe często wymagają obsługi wielu języków. Silverlight podobnie jak ASP .NET wspiera mechanizm globalizacji za pomocą zasobów (resources files). Pliki zasobów są tak naprawdę zwykłymi plikami XML. Stanowi to ogromną zaletę – za pomocą zewnętrznego narzędzia odpowiednie osoby  mogą przygotować tłumaczenie interfejsu.

Najpierw należy stworzyć główny plik zasobów. Zawiera on tłumaczenia dla domyślnego języka. W przypadku gdy użytkownik pochodzi z kraju, którego język nie jest obsługiwany przez naszą aplikację to właśnie domyślne zasoby będą ładowane. Tworzymy więc plik zasobów za pomocą Add –> New Item –>Resources File. Nazwę pliku pozostawiamy domyślną:

image

Naszym domyślnym językiem będzie angielski. Dopisujemy więc przykładowy zasób o nazwie HELLO_WORLD_LABEL z wartością “Hello world!”:

image

Tworzymy drugi zasób odpowiedzialny za język polski. Jako nazwę podajemy “Resource1.pl-PL.resx”. Tym razem nazwa jest bardzo istotna ponieważ po niej właśnie ładowane są pliki w zależności od ustawień regionalnych użytkownika.

image

Podobnie jak w przypadku zasobu domyślnego, tworzymy wpis “HELLO_WORLD_LABEL” z przetłumaczoną zawartością (“Witaj świecie!”).

image

W tej chwili mamy już przygotowane zasoby. Przyszedł czas na wykorzystanie ich w programie. W pliku SL (MainPage.xaml) tworzymy pojedyncza kontrolkę Label:

<UserControl xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input"  x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">

    <Grid x:Name="LayoutRoot">
        <dataInput:Label x:Name="m_Label"></dataInput:Label>
    </Grid>
</UserControl>

Wykorzystanie zasobów za pomocą kodu jest bardzo proste. Wystarczy użyć automatycznie wygenerowaną klasę Resources1. Odpowiednie przypisanie można wykonać w konstruktorze klasy UserControl (MainPage.xaml):

public MainPage()
{
    InitializeComponent();
    m_Label.Content = Resource1.HELLO_WORLD_LABEL;
}

Na dzień dzisiejszy niestety trzeba dodatkowo ręcznie wyedytować plik projektu Silverlight. Otwieramy zatem SilverlightApplication1.csproj i znajdujemy element SupportedCultures. Wewnątrz tego elementu dopisujemy pl-PL:

<SupportedCultures>
      pl-PL
</SupportedCultures>

Ostatnią rzeczą, którą należy zrobić jest odpowiednie skonfigurowanie obiektu Silverlight w HTML. Należy przekazać dwa dodatkowe parametry – “culture”

oraz “uiculture”:

<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
      <param name="culture" value="pl-PL" />
      <param name="uiculture" value="pl-PL" />
      
      <param name="source" value="ClientBin/SilverlightApplication1.xap"/>
      <param name="onError" value="onSilverlightError" />
      <param name="background" value="white" />
      <param name="minRuntimeVersion" value="3.0.40818.0" />
      <param name="autoUpgrade" value="true" />
      <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40818.0" style="text-decoration:none">
          <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
      </a>
</object>

Wartość ustawiamy  w zależności od języka, który chcemy wykorzystać (w powyższym przypadku jest to język polski). Wartości odpowiadają zarówno za wygląd interfejsu (tłumaczenia) jak i za formatowanie walut, liczb, dat itp.

Po odpaleniu strony powinniśmy ujrzeć polską wersje aplikacji:

image

W celach testowych zmieńmy język na jakiś nieobsługiwany:

<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
      <param name="uiculture" value="pt-BR" />
      <param name="culture" value="pt-BR" />

      <param name="source" value="ClientBin/SilverlightApplication1.xap"/>
      <param name="onError" value="onSilverlightError" />
      <param name="background" value="white" />
      <param name="minRuntimeVersion" value="3.0.40818.0" />
      <param name="autoUpgrade" value="true" />
      <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40818.0" style="text-decoration:none">
          <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
      </a>
</object>

Po odpaleniu przeglądarki załaduje się domyślny plik zasobów (Resources1.resx) zawierający w naszym przypadku angielskie tłumaczenie:

image

Wiemy jak już wykorzystać zasoby z poziomu kodu. Interfejs jednak powinno definiować się w pliku XAML. Zasoby można podczepiać w XAMl za pomocą binding’u. Oto przykład:

<UserControl xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input"  x:Class="SilverlightApplication1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    
    xmlns:local="clr-namespace:SilverlightApplication1"
             
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
    <UserControl.Resources>
        <local:Resource1 x:Key="ResourceHelper"/>        
    </UserControl.Resources>
  <Grid x:Name="LayoutRoot">
    <dataInput:Label Content="{Binding Path=HELLO_WORLD_LABEL,Source={StaticResource ResourceHelper}}" x:Name="m_Label"></dataInput:Label>        
  </Grid>
</UserControl>

W pliku (MainPage.xaml) nastąpiły 3 zmiany:

  1. Została podpięta przestrzeń nazw w której znajduje się klasa zasobów (Resource1):

    xmlns:local="clr-namespace:SilverlightApplication1"
  2. Aby móc korzystać z zasobu w XAML należy go zadeklarować i nadać klucz:

    <UserControl.Resources>

        <local:Resource1 x:Key="ResourceHelper"/>       
    </UserControl.Resources>

  3. Następnie za pomocą statycznego wiązania wystarczy podpiąć HELLO_WORLD_LABEL:

    <dataInput:Label Content="{Binding Path=HELLO_WORLD_LABEL,Source={StaticResource ResourceHelper}}" x:Name="m_Label"></dataInput:Label>       

Ponadto należy zmienić modyfikatory internal na public w pliku Resources1.Designer.cs. Bez tego binding nie zadziała!

Kompletny kod źródłowy znajduje się tutaj.

4 thoughts on “Silverlight – lokalizacja aplikacji”

Leave a Reply

Your email address will not be published.