You may want to put some text here

Csharp Programma in meerdere talen met WPF

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.

Vertaling van een applicatie tijdens runtime

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.

Nieuw C# WPF applicatie

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.

Nieuwe map aanmaken

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

<?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

<?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.

Applicatie layout
<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.

<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.

{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:

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:

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:

loadLanguage("english");

Hopelijk is het allemaal wat duidelijk. Als je nog vragen hebt mag je deze altijd hieronder stellen.

The Author of this post is Wim Mostmans

Wim Mostmans heeft een eigen webontwikkeling bedrijf Sitebase waar hij voltijds voor werkt. Hij beheert ook nog enkele websites waaronder deze en een Computerforum. Blijf op de hoogte van waar Wim mee bezig is door hem te volgen op Twitter.

2 Responses »

  1. Goeie tutorial Wim. Dit was juist wat ik nodig had voor een klein programmaatje dat ik aan het schrijven ben voor het school.

  2. Hallo,

    Ik zou graag mijn GUI meertalig maken, het probleem is alleen dat jij alleen maar de XAML code geeft. Ik heb de GUI al in C# gemaakt, nou weet ik alleen niet hoe je die 2 zinnen in C# zet om die XML aan te roepen, gezien dit in XAML taal is

Leave a Comment