Question Switch languages in VB forms and strings

Budius

Well-known member
Joined
Aug 6, 2010
Messages
137
Location
UK
Programming Experience
3-5
Hi,

I've seen quite a few posts regarding changing cultures, localize cultures, etc... but I couldn't care less about all that auto-stuff.

I'm developing this GUI to connect with one of our production machines that will be used by the ppl who will be servicing the machines.
Which might well be anywhere around Europe and soon enough Japan and US.
Therefore, it was asked already to have language options, cause the guy servicing is likely to be a local.

As I said, auto-stuff doesn't bother me, all I want is the option to go to File -> Preferences and change a drop-down box to whatever language the person fancy and put a My.Settings.Save()

I'm planning to create a few simple xml files called "en", "fr", "sp", etc which will be something like:
VB.NET:
<Frm_Main.Label1>Text of the label</Frm_Main.Label1>

The actual problem is:
I know the coded strings will have to be manually set, but: Is there a way to cycle through all the UI items (labels, toolstripmenu, buttons, group boxes) to set those .text ??
I'm trying stuff like
VB.NET:
For each ctrl as Control in me.Controls
but it does not get everything. I'm really trying to avoid to do it manually one-by-one.
Also if I get to cycle through all of it, I can use the code to generate the 1st XML (as a template) ...

any ideas ??
am I going through an absurdly wrong approach?
is there any better/easier/sound way of doing multi-language GUI?

thanks
 
I don't know how simple or how hard it'll be to do something like this, but here's a couple of articles on the matter that may help:
DotNet Visual Basic: Creating multilanguage forms ,DotNet Visual Basic. - dotnet.itags.org
Multilingual Applications in .NET

From the looks of it, you might be able to just set the culture and your form & coded strings will automatically be displayed in their language without them needing to select one, it'll just use the system's one that it's on. Like I said I've never done something like this so I don't know how it works.
 
thanks for the links...
I had a look on them, but they still rely on the lengthy boring job of manually create a dictionary with:
VB.NET:
label1=Hello World
     --- OR ----
<data name="label1">
     <value>Hello World</value>
</data>
and then individually set each piece of string or text or tag with a
VB.NET:
Label1.Text = x.GetString("label1")

I kinda ended up doing:
en.xml
VB.NET:
<?xml version="1.0" encoding="utf-8" ?>
<en>
  <Main>
    <FileToolStripMenuItem>File</FileToolStripMenuItem>
    <LanguageStripMenuItem>Language</LanguageStripMenuItem> ... etc
then created a pt.xml, fr.xml ... etc
and OnLoad of my forms I do:
VB.NET:
Me.FileToolStripMenuItem.Text = r.text(Me.Name, Me.FileToolStripMenuItem.Name)
Me.LanguageStripMenuItem.Text = r.text(Me.Name, Me.LanguageStripMenuItem.Name) ... etc
for each single GUI element, plus hardcoded strings for message boxes are also calling r.text("Strings", "StringIdentifier")

for anyone interested the r.text code is:
VB.NET:
    Function text(ByVal Frm As String, ByVal Item As String) As String
        Dim language As String

        Select Case My.Settings.Language
            Case 0 : language = "en" ' English
            Case 1 : language = "pt" ' Portuguese
            Case Else : language = "en" ' English
        End Select

        Dim XmlFile As IO.Stream

        Try
            Dim myEnc As New System.Text.UTF8Encoding
            XmlFile = New MemoryStream(myEnc.GetBytes(My.Resources.ResourceManager.GetString(language)))

        Catch ex As Exception
            XmlFile = Nothing
            Return "- error -"
        End Try

        Dim reader As New Xml.XPath.XPathDocument(XmlFile)
        Dim nav As Xml.XPath.XPathNavigator = reader.CreateNavigator
        Return nav.SelectSingleNode("//" & Frm & "/" & Item).Value

    End Function


even thou my work is just replicate the boring part through all the code, if anyone got an experience on it or some clever idea I didn't notice.. I'm reading the thread!
 
thanks for the links...
I had a look on them, but they still rely on the lengthy boring job of manually create a dictionary with:
Actually, if you want you can write this right into the forms in Designer, just set the Language property of the form and type in all localized strings. When doing this in Designer you can read which language is currently being edited right from the form tab. Now you can change culture and load a form with correct language:
VB.NET:
My.Application.ChangeUICulture("de")
Dim f As New SomeForm
f.Show()
It's "auto-stuff", but very convenient :) What's happening behind the scenes is that a localized form creates a ComponentResourceManager in InitializeComponents method (called from forms constructor) and does a ApplyResources call for each component/control. The resource strings are auto generated to satellite assemblies and included with app deployment. More about the "auto", if such a localized form is opened in a computer that has that locale set as default it will automatically show the correct language strings (without code needed to change culture), but I guess explicitly changing the culture for current app was your goal.
 
sounds interesting BUT,
can I go through the "auto-stuff" and edit into proper translations or do I have to stick with it ?




OK, nevermind I got it...
I thought it would be much more of a manual process, but in the end, it's pretty much like supervisory systems.
I'll still have to mess around with the hardcoded strings that are dumped to excel or shown in lil message boxes or listBoxe4s...

but it already speed up a lot the process....
 
Last edited:
I'll still have to mess around with the hardcoded strings that are dumped to excel or shown in lil message boxes or listBoxe4s...
If you mean messages you app produces then I'd include these in similar localized resource files. For example you add a messages.resx file and can add name/value pairs in resource editor page (open the file), then local files with same keys, for example messages.de.resx. In app you can then use a ResourceManager and GetString(key) to get the message in correct language. The 'manually' section here diescribes this: Walkthrough: Localizing Windows Forms
 
Hi again...
Thanks for all the help, I definitely see the advantages of using it over a manual method (even with some limitations express edition have there), but I'll stick with the manual method and I explain why:
I'm not the one doing the actual translations, and translations might happen now or in 3 years time... so the xml I created are far more simpler than the the .resx (which are both complex and distributed across multiple files) and it just makes it simple for me to copy the content, sent it to the translation company and get a result we could just paste into the project and the new translation is done.

thanks again for the help guys.
 
In express you just have to add a file and give it .resx extension.

Since the translations are in satellite assemblies they can be added later, how they are added could be discussed, but I don't see this as an issue. There are for example ways your app could generate them given any kind of information source.

One file or multiple files? Whatever achieves the goal in simplest way and makes all parties happy :)
 
As I said before (but maybe didn't properly explain), it's not about the assembly or my technical difficulty anymore... and I'm sure that what I'm doing now it's more hard work for me.

It's more a logistics issue of having all the text in a single file with an easy enough formatting for a totally non-technical person (from the translation company) to be able to translate it without the need of someone here to check the whole file(s) again for incorrect formatting because the person deleted a > or / by accident. (and believe me, they do)
 
You can take that source information and use ResourceWriter class to write out all the key/values to a .resources file, this is what VS compiles from the .resx source. Something like this:
VB.NET:
Using res As New Resources.ResourceWriter("messages.de.resources")
    For Each keyvalue In sourcedata
        res.AddResource(key, value)
    Next
End Using
After that use the .Net tool al.exe to produce the satellite dll and place it in correct folder. Now, without any additional work on your side you have added a new language translation to the app. Creating Satellite Assemblies

Btw, I'd not give the non-tech translator a text file to mess with/up. Create a simple app with a key/value table that presents the key, the text to translate, and input field for translation. Add an option to select the culture to translate for and produce the satellite straight from that.
 
Btw, I'd not give the non-tech translator a text file to mess with/up. Create a simple app with a key/value table that presents the key, the text to translate, and input field for translation. Add an option to select the culture to translate for and produce the satellite straight from that.
you're so damn right about it...

There are other translations going on here for stuff developed in supervisory systems (Siemens WinCC) that I'm so scared to see what will return to me from the original excel exported file. But, we've (controls department) told them (marketing, the ones who sold it to Spain) that that's not the way to do it.

But on this case, as it's VB.net... I have the control over it.
Yeah.. I'll create an app just for the translators to use.

good suggestion... cheers!
 
Back
Top