Als je wat grotere programma’s begint te schrijven en/of je wilt deze gaan verspreiden in het buitenland dan is het zeker een goed idee om je applicatie in meerdere talen te maken. Wat je kan doen is twee verschillende versies compileren bijvoorbeeld een engelse en een nederlandse versie. In deze tutorial ga ik je echter een andere oplossing tonen. Ik zal je laten zien hoe je een versie van je applicatie kan compilen en waar er tijdens runtime (tijden dat het programma opstaat) de taal kan gewijzigd worden.

De applicatie
Tijdens deze tutorial ga je het onderstaande kleine applicatie maken waarmee je twee getallen kan laten optellen. Als we op de knop Engels drukken dan zal de hele applicatie vertaald worden naar het engels. Druk je op Nederlands, dan zal de hele applicatie vertaald worden naar het nederlands.

Start een nieuwe C# WPF applicatie. Kies bovenaan het Nieuw project menu voor het .NET Framework 3.0 of 3.5. Bij naam vul je MeerTalen in. Vervolgens klik je op OK.
Maak nu eerst een map aan binnen je project. Dit doe je door met je linkermuisknop te klikken op MeerTalen > Toevoegen… > Nieuwe map. Geef deze map de naam languages.

Maak nu onder deze map languages twee nieuwe xml bestanden aan. Dit doe je door linkermuisknop te klikken op de map languages > Toevoege … > Nieuw item … . Kies uit het menu het type xml bestand. Noem dit nieuw bestand dutch.xml. Herhaal deze stappen maar noem het bestand deze keer english.xml. Plak de volgende xml in het juist bestand. Deze xml’s zijn de vertalingen van de applicatie.
dutch.xml
0 1 2 3 4 5 6 7 8 | <?xml version="1.0" encoding="utf-8" ?> <Example> <Calculator Text="Rekenmachine"/> <NumbersError Text="Geeft 2 getallen op."/> <Calculate Text="Bereken"/> <ResultIs Text="Het resultaat is"/> <Dutch Text="Nederlands"/> <English Text="Engels"/> </Example> |
english.xml
0 1 2 3 4 5 6 7 8 | <?xml version="1.0" encoding="utf-8" ?> <Example> <Calculator Text="Calculator"/> <NumbersError Text="Fill in 2 numbers."/> <Calculate Text="Calculate"/> <ResultIs Text="The result is"/> <Dutch Text="Dutch"/> <English Text="English"/> </Example> |
Maak nu onderstaande layout na of plak de onderstaande XAML code in de XAML editor.

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <Window x:Class="MeerTalen.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Voorbeeld" Height="274" Width="300"> <Window.Resources> <XmlDataProvider x:Key="LanguageProvider" Source="/languages/dutch.xml" XPath="Example"/> </Window.Resources> <Grid> <Label Height="28" HorizontalAlignment="Left" Margin="10,11,0,0" Name="lblCalculator" VerticalAlignment="Top" Width="113" FontSize="16" Content="{Binding Source={StaticResource LanguageProvider}, XPath=Calculator/@Text}"/> <Label Name="lblError" Foreground="Red" Margin="15,41,59,0" Height="25" VerticalAlignment="Top" Visibility="Hidden" Content="{Binding Source={StaticResource LanguageProvider}, XPath=NumbersError/@Text}"/> <Button Margin="15,104,15,95" Name="btnCalculate" Click="btnCalculate_Click" Content="{Binding Source={StaticResource LanguageProvider}, XPath=Calculate/@Text}"/> <TextBox Height="26" HorizontalAlignment="Left" Text="40" Margin="15,68,0,0" Name="txtNumber1" VerticalAlignment="Top" Width="99" FontSize="14" /> <Label Height="28" Margin="130,68,125,0" Name="lblPlus" VerticalAlignment="Top">+</Label> <TextBox Height="26" HorizontalAlignment="Right" Text="50" Margin="0,68,15,0" Name="txtNumber2" VerticalAlignment="Top" Width="100" FontSize="14" /> <StackPanel Name="stkResult" Orientation="Horizontal" Visibility="Hidden"> <Label Height="28" Margin="15,0,0,61" Name="lblResult1" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="106" FontSize="14" Content="{Binding Source={StaticResource LanguageProvider}, XPath=ResultIs/@Text}"/> <Label Height="28" Margin="15,0,0,61" Name="lblResult2" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="42" FontSize="14"></Label> </StackPanel> <Button Height="32" HorizontalAlignment="Left" Margin="15,0,0,13" Name="btnDutch" VerticalAlignment="Bottom" Width="116" Content="{Binding Source={StaticResource LanguageProvider}, XPath=Dutch/@Text}" Click="btnDutch_Click" /> <Button Height="32" HorizontalAlignment="Right" Margin="0,0,15,13" Name="btnEnglish" VerticalAlignment="Bottom" Width="116" Content="{Binding Source={StaticResource LanguageProvider}, XPath=English/@Text}" Click="btnEnglish_Click" /> </Grid> </Window> |
Het belangrijkste aan bovenstaande code zijn de volgende twee dingen.
0 | <XmlDataProvider x:Key="LanguageProvider" Source="/languages/dutch.xml" XPath="Example"/> |
Deze regel gaat bepalen welk bestand gebruikt gaat worden om de teksten van de applicatie uit te halen. En als tweede hebben we de Binding nog die gaat zorgen dat het juist tekst deel uit het xml bestand gaat gehaald worden voor elk element in de interface.
0 | {Binding Source={StaticResource LanguageProvider}, XPath=Calculate/@Text} |
De staticresource LanguageProvider verwijst naar de xmldataprovider welke bepaald welk xml bestand er gebruikt moet worden. Het XPath bepaald welk tekst element er uit de xml gehaald gaat worden. In dit geval het attribuut Text binnen het element Calculate.
Open nu de code editor van het venster en plak er de volgende code in:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.IO; using System.Xml; namespace MeerTalen { public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void btnCalculate_Click(object sender, RoutedEventArgs e) { string number1 = txtNumber1.Text; string number2 = txtNumber2.Text; if (!checkNumber(number1) || !checkNumber(number2)) { lblError.Visibility = Visibility.Visible; } else { int intnumber1 = int.Parse(number1); int intnumber2 = int.Parse(number2); stkResult.Visibility = Visibility.Visible; lblError.Visibility = Visibility.Hidden; lblResult2.Content = intnumber1 + intnumber2; } } private bool checkNumber(string input) { for (int i = 0; i < input.Length; i++) { if (!Char.IsNumber(input[i])) { return false; } } return true; } public void loadLanguage( String language ) { XmlDataProvider xmlData = (XmlDataProvider)(this.FindResource("LanguageProvider")); String url = "pack://application:,,,/languages/" + language + ".xml"; xmlData.Source = new Uri(url); } private void btnDutch_Click(object sender, RoutedEventArgs e) { loadLanguage("dutch"); } private void btnEnglish_Click(object sender, RoutedEventArgs e) { loadLanguage("english"); } } } |
Al de bovenstaande code is zowat basis code voor de werking van de applicatie. Het enige wat belangerijk is voor de vertaling is het volgende:
0 1 2 3 4 5 | public void loadLanguage( String language ) { XmlDataProvider xmlData = (XmlDataProvider)(this.FindResource("LanguageProvider")); String url = "pack://application:,,,/languages/" + language + ".xml"; xmlData.Source = new Uri(url); } |
De eerste regel gaat de XmlDataProvider (LanguageProvider) zoeken in de XAML-code. Op de twee volgende code’s wordt dan de source van deze dataprovider aangepast naargelang welke taal er wordt meegegeven aan de methode.
Als je de taal van de applicatie wilt laten veranderen dan moet je maar één regel code schrijven om dit te doen. Wil je bijvoorbeeld dat de applicatie naar het engels vertaald wordt, dan gebruik je de volgende lijn code:
0 | loadLanguage("english"); |
Hopelijk is het allemaal wat duidelijk. Als je nog vragen hebt mag je deze altijd hieronder stellen.
Goeie tutorial Wim. Dit was juist wat ik nodig had voor een klein programmaatje dat ik aan het schrijven ben voor het school.
Reactie door Ben — 16 juli 2008 23:52 @ 23:52