How do you translate your WinForms app? (outsourcing localization)

J

Joergen Bech

Suppose I have written a .Net application and - until now -
have hardcoded all my text strings. Now, the application needs
to be translated into another language. Furthermore, the translation
must be done by someone at the other end of the world, without
access to Visual Studio.

I suppose the first thing to do would be to make sure that all
strings are loaded from resource files, but what about the language
editor and language switching?

I heard about winres.exe, but my application makes use of many
custom usercontrols and winres.exe often chokes on the forms I
try to feed it. Also, I am not sure about relying on reflection to
change all my captions, etc. To be able to switch language without
restarting the application, I believe I would still need to write some
custom code to be executed on all open forms (to update dynamic
information) even if I use winres.exe(?)

Questions:

1) Do you use winres.exe and try to make your application play nice
with this utility?

2) What about dynamic elements not editable by winres.exe? Do you
implement a standard method in all your forms and cycle through
all open forms, calling this method whenever a culture change is
requested? Or is there something built into the framework I can
use? I would prefer *not* having my forms torn down and rebuilt
(even behind the scenes) for the translation to take place.

3) Are there any good alternatives (commercial or free) to winres.exe
or do I have to roll my own?

4) Any links to information/best practices on this subject?

/Joergen Bech
 
R

Robinson

I would also love to hear about this. It seems to be one of those areas
where you have to choose between craptastic free tools and repetitive strain
injury or craptasticly expensive professional tools that never do exactly
what you want them to (i.e. WinTrans 8.0). Having said that, your biggest
bill is going to be from the translator ;).



Robin
 
O

Olaf Rabbachin

Hi,

Joergen said:
I suppose the first thing to do would be to make sure that all
strings are loaded from resource files, but what about the language
editor and language switching?

checkout this thread in microsoft.public.dotnet.framework.aspnet:

Basically, what I do is using a database that holds all textual contents.

If you'd like to stick with the resources-approach, here's two links that
I've come across, the first being geared at SQLS and the second at Access:
http://www.codeproject.com/aspnet/customsqlserverprovider.asp
http://www.leftslipper.com/ShowFaq.aspx?FaqId=9
Haven't tried this out yet though.

Concerning the translations, I tend to distribute Access-DBs with WinForms,
along with an application that can be used to translate items. That
application will then be sent to translators and they then send back the
MDB which may then replace the local database(s).
In ASP.Net I have pages that map the same functionality and may used by
translators directly over the web (provided we're talking internet as
opposed to intranet).
2) What about dynamic elements not editable by winres.exe? Do you
implement a standard method in all your forms and cycle through
all open forms, calling this method whenever a culture change is
requested? Or is there something built into the framework I can
use? I would prefer *not* having my forms torn down and rebuilt
(even behind the scenes) for the translation to take place.

Not sure what you're talking about here. If this is about i.e.
product-names which are actually defined by the users themselves: In my
current project, this is handled by extending the identifier (or key) with
a suffix - the record's ID. That is, when a product is being added to the
database, a new record for every language will be added to the text-table
along with the internal title (which needs to be set before adding). It's
up to the user to then supply the texts required to display the item in the
languages that exist.

Cheers & tschüssele,
Olaf
 
O

Olaf Rabbachin

Hi,
I would also love to hear about this. It seems to be one of those areas
where you have to choose between craptastic free tools and repetitive strain
injury or craptasticly expensive professional tools that never do exactly
what you want them to (i.e. WinTrans 8.0).

I don't think so. The setup is actually pretty simple. Basically:

- tblLanguages
Contains one entry per Language (title, native name, SortOrder, Culture,
Active, MayBeDeleted)
- tbl_Language_Info
Contains information about the background of items (one rec for every
text-key)
- tbl_Language_Text
Contains one record per language per text to be displayed, plus a FK to
link to the language. Arguments will be included so that they may be
replaced via string.format()

From .Net, I have a class that consumes the database and returns texts that
are identified by the language's ID and the appropriate text-key.
I haven't tried this with either right-2-left languages or i.e. chinese,
but other than that this works pretty well.
Having said that, your biggest bill is going to be from the translator
;).

Probably ... :)

Cheers,
Olaf
 
J

Joergen Bech

Hi,



checkout this thread in microsoft.public.dotnet.framework.aspnet:

Basically, what I do is using a database that holds all textual contents.

If you'd like to stick with the resources-approach, here's two links that
I've come across, the first being geared at SQLS and the second at Access:
http://www.codeproject.com/aspnet/customsqlserverprovider.asp
http://www.leftslipper.com/ShowFaq.aspx?FaqId=9
Haven't tried this out yet though.

Concerning the translations, I tend to distribute Access-DBs with WinForms,
along with an application that can be used to translate items. That
application will then be sent to translators and they then send back the
MDB which may then replace the local database(s).
In ASP.Net I have pages that map the same functionality and may used by
translators directly over the web (provided we're talking internet as
opposed to intranet).

Yes, this is what I used to do back in the old VB6 days. I could
convert my old tools and ways of doing it to .Net, but before I go
that route, I wanted to know if there was a standard approach
specific to .Net (or a de facto tool).
Not sure what you're talking about here. If this is about i.e.
product-names which are actually defined by the users themselves: In my
current project, this is handled by extending the identifier (or key) with
a suffix - the record's ID. That is, when a product is being added to the
database, a new record for every language will be added to the text-table
along with the internal title (which needs to be set before adding). It's
up to the user to then supply the texts required to display the item in the
languages that exist.

By "dynamic" elements I mean text strings that are composed by the
program during runtime, i.e. a progress dialog might display
"Now processing record 1 of 457". This string would be stored as
"Now processing record %1 of %2" in the language database and
the %1 and %2 placeholders would be replaced at runtime after the
string had been translated.

Could be any number of other things that cannot be translated at
designtime.

/Joergen Bech
 
R

RobinS

Joergen Bech @ post1.tele.dk> said:
Yes, this is what I used to do back in the old VB6 days. I could
convert my old tools and ways of doing it to .Net, but before I go
that route, I wanted to know if there was a standard approach
specific to .Net (or a de facto tool).


By "dynamic" elements I mean text strings that are composed by the
program during runtime, i.e. a progress dialog might display
"Now processing record 1 of 457". This string would be stored as
"Now processing record %1 of %2" in the language database and
the %1 and %2 placeholders would be replaced at runtime after the
string had been translated.

Could be any number of other things that cannot be translated at
designtime.

/Joergen Bech

But you *can* process those strings at designtime.
Store them as something like

"Now Processing Record {0} of {2}."

Then use String.Format to output them in your program:

message = String.Format(stringFromDb, 1, 457)

Robin S.
 
J

Joergen Bech

But you *can* process those strings at designtime.
Store them as something like

"Now Processing Record {0} of {2}."

Then use String.Format to output them in your program:

message = String.Format(stringFromDb, 1, 457)

Robin S.

Yes, I know, and that is what I was describing. The thing is:
Are such strings visible/editable in winres.exe and is there something
in the framework that (via reflection?) causes certain functions to
be called automatically when a new culture is applied to a form?

Remember: I would like to be able to translate forms and controls
(including "dynamic" elements) without restarting the application
and without even tearing down and rebuilding the forms. So some
mechanism needs to be in place to fetch those strings, process them,
and display them to the user. Question is, do I write the whole thing
myself or do I get parts of it for "free"?

/Joergen Bech
 
R

RobinS

Joergen Bech @ post1.tele.dk> said:
Yes, I know, and that is what I was describing. The thing is:
Are such strings visible/editable in winres.exe and is there something
in the framework that (via reflection?) causes certain functions to
be called automatically when a new culture is applied to a form?

Remember: I would like to be able to translate forms and controls
(including "dynamic" elements) without restarting the application
and without even tearing down and rebuilding the forms. So some
mechanism needs to be in place to fetch those strings, process them,
and display them to the user. Question is, do I write the whole thing
myself or do I get parts of it for "free"?

/Joergen Bech

I haven't done this, but am generally suspicious of anything free.
Personally, I like to have control. So I would follow the other
suggestions and put the strings in a database table and get them
from there depending on the location in which I am running.

Robin S.
 
O

Olaf Rabbachin

Hi,

Joergen said:
By "dynamic" elements I mean text strings that are composed by the
program during runtime, i.e. a progress dialog might display
"Now processing record 1 of 457". This string would be stored as
"Now processing record %1 of %2" in the language database and
the %1 and %2 placeholders would be replaced at runtime after the
string had been translated.

Could be any number of other things that cannot be translated at
designtime.

since I never went the resources- resp. "built-in" path I actually don't
know. :)

Cheers,
Olaf
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top