Ref till tråden [Flera språk i sitt program],! Hej, saw, när du har lyckats med att utnyttja Recource Managern så kan du ju berättar hur du gjorde för mig. Har själv faktiskt inte fått rätt på det. Vad är det du inte lyckas med? Hinner inte föklara ås mkt, skall strax in i ett möte. :-( Hej Johan och tack för att du försöker. Hej Johan och tack för att du försöker. Hej, Hej, TACK. Hej, Nu har jag också fått rätt på det. Har bara ett problem. Då har jag kanske dabbat mig (igen), men det vill sig inte. det finns en culture, CurrentUiCulture :) sorry, Det är tydligen en sådan dag igen... saw, ändrar inte sig språket i applikationen nu då? Var det inte det du ville åstadkomma? Hej Martin. När din Form initieras eller rättare sagt i konstruktorn i din Form så läses din resursfil in och sätter alla kontrollers texter och lite andra egenskaper till det språk som kulturen har då. När du sedan i din app ändrar trådens språk genomat att sätta CurerntUICuture, så sätter den automatiskt inte om kontrolelrnas texter till rätt språk för det finns inget som triggar att ny resurs ska läsas in etc, du anger bara att tråden ska använda en annan kultur inget annat. Efter att du har ändrat kulturen på tråden så måste du läsa in resursfilen på nytt och sätta om alla kontrollernas egenskaper. Ok tack, det var lite mera extra jobb än vad jag hadde förväntat men... Om du använder windows forms så behöver du inte hantera resurserna för hand det finns ett inbyggt sätt. Daniel: Nu är denna tråd egentligen löst men skulle någon vara snäll och svara på min fråga, som jag ställde lite längre upp ? Martin! Hur kommer jag åt kontrollerna i de övriga formulären från mitt main formulär ? Jag har lyckats ändra på mina menyer men knappar och annat som ligger i andra formulär kommer jag inte åt. Hur har du gjort ? Om du har kollat in min andra tråd [Spara inställningarna i vi XML] så har jag nu lärt mig att spara och hämta värden (serilisation), och när jag öppnar upp någonting annat så får formuläret läsa in språket som jag vill ha. du kan ju sätta publika åtkomst metoder för kontrollerna men det känns som om du angriper felet från fel håll... Hur som helst har jag tolkat dig som att det bästa är att skapa ett Interface som innehåller en metod som tex heter change(). I varje formulär implementerar jag change() metoden som ändrar språket för just deras kontroller. När jag sedan väljer engelska som språk så anropar jag helt enkelt change() metoden som då kommer att göra ändringar för resp. formulär Jovisst, men ett interface är ju mer generellt. Du kanske inte bara vill ha Formulär som du vill byta språk på utan nånting annat... då kan det ju vara bra med ett interface, men som sagt det går bra med en vanlig publik metod. Sen kan man ju diskutera om metodens namn ska vara Change... eller om man skall ha ett mer beskrivande namnFlerspråks-stöd
Jag försöker att få in flerspråksståd, och den första biten var ju enkel.
Om jag innan InitializeComponent(); lägger till
<code>
System.Threading.Thread.CurrentThread.CurrentUICulture= new System.Globalization.CultureInfo("en-US");
</code>
så är det ju lätt att ändra. Vad jag förstår så måste applikationen startas om, så man kan inte ha en listbox med de olika språken, men om man skriver till registret, så löser ju det sig.
Vad jag inte förstår är hur jag skall utnyttja ResourceManager.
Jag har nu på test skappat två resursfiler,
ResEng
ResSv
Nu gäller det ju att ladda dessa?
Jag har gjort så här (bara för att testa) så kallar jag den första "posten"(name) string1 i bägge resursfilerna, och har sedan engelska resp svenska.
Hur använder jag mig av detta sedan? Sv: Flerspråks-stöd
Dui behöver inte använda något register, och sedan vill jag lämna ett gott råd. Använd inte registret, aldrig någonsin, det är MS största misstag att låta folk härja villt där. Folk lägger in en massa skit, tar sedan inte bort dem, gör andra inställningar som påverkar Operativet, återställer ej vid avinstallation m.m. så tillslut har du ett trasigt och tungt OS :-( Så bäst är att inte spara saker där i utan köra egna XML filer eller liknande för special configuration för sin applikation. På detta sätt blir även deployment och installation lättare. Och återanvändbarheten av inställningar går att spara undan eller kopiera till nästa applikation. Utan att man måste exportera register stärngar...
När du ändrar kultur slår det genom med en gång. Så du behöver inte starta om applikationen, det är tråden du justerar och den är alltid levande under din app domän.
Resursmanagern kommer automatisk ta den fil som passar ditt språk.
Du måste ange dina språkfiler på ett visst sätt för att automatiskt få med dem.
Ex defaultfilen om inte ResourceManager hittar fil passande språket kan vara:
Strings.resx om du sedan döper en fil till Strings.en.resx och du har satt en engelsk kultur så kommer ResourceManager Automatiskt läs in denna. Så string.<cultur>.resx döper du alla filer till som du vill ha språkhantering på.
Är du med?
Var det detta du undrade?
Mvh JohanSv: Flerspråks-stöd
Sv: Flerspråks-stöd
ALlt? att få ut rätt data? hur man bygger logiken?
Mvh JohanSv: Flerspråks-stöd
Men här har du lite kod.
<code>
name = "Foo";
ResourceManager resourceManager = new ResourceManager("Foo.Resource",Assembly.GetExecutingAssembly());
String ResourceResult = resourceManager.GetString(name);
</code>
Fördsta raden skapar jag objektet inte så svårt. Det man bör tänk på här är att du sätter din resource fil som embeded. (Om du vill ha en satelite assembly av den) remomenderas för denna användning.
Man måste ange hela namespacet plus filens namn, dock utan endelsen.
så döper du filen till strings.resource skall du baran ange <namespace>.strings.
Sedan tar den emot Assemblyn som den skall hitta resourcedatan i. I detta fall blir det den assembly vi exekverar. (alltså där du har denna koden) i annat fall måste ni göra om ert objekt till en assembly klass och skicka in den.
Sedan så lägger man till ett name i er resourcefil och ett värde. För att plcoka ut värdet kan man använda olika metoder i detta fall använder jag GetString(), där jag anger namnet på den data jag vill komma åt. Klart. Har man nu string.en.resource och sätter kulturen på detta kommer resourcemanagern automatiskt plocka datan från den.
mvh JohanSv: Flerspråks-stöd
Detta är helt nytt för mig, så jag värdesätter all hjälp.
Vi tar ett problem i sänder:
Jag har skappat två resource filer
strings.en.resx
strings.sv.resx
I dem så har jag gjort
name string1
value lite text på olika språk
Så långt är vi nog överens.
Problemet är att läsa in detta (jag har nog testat ett 30 tal olika lösningar)
<code>
string name = "string1";
ResourceManager resourceManager = new ResourceManager("strings.Resource",Assembly.GetExecutingAssembly());
String ResourceResult = resourceManager.GetString(name);
MessageBox.Show(ResourceResult);
</code>
..och detta generera följande fel
<code>
An unhandled exception of type 'System.Resources.MissingManifestResourceException' occurred in mscorlib.dll
Additional information: Det gick inte att hitta några resurser för den angivna kulturen (eller den neutrala kulturen) i den aktuella sammansättningen. Kontrollera att strings.Resource.resources har bäddats in i eller länkats till sammansättningen WindowsApplication1 korrekt.
baseName: strings.Resource locationInfo: <null> resource file name: strings.Resource.resources assembly: WindowsApplication1, Version=1.0.1535.20080, Culture=neutral, PublicKeyToken=null
</code>
Jag gör väll galet någonstans, men var??Sv: Flerspråks-stöd
Detta är helt nytt för mig, så jag värdesätter all hjälp.
Vi tar ett problem i sänder:
Jag har skappat två resource filer
strings.en.resx
strings.sv.resx
I dem så har jag gjort
name string1
value lite text på olika språk
Så långt är vi nog överens.
Problemet är att läsa in detta (jag har nog testat ett 30 tal olika lösningar)
<code>
string name = "string1";
ResourceManager resourceManager = new ResourceManager("strings.Resource",Assembly.GetExecutingAssembly());
String ResourceResult = resourceManager.GetString(name);
MessageBox.Show(ResourceResult);
</code>
..och detta generera följande fel
<code>
An unhandled exception of type 'System.Resources.MissingManifestResourceException' occurred in mscorlib.dll
Additional information: Det gick inte att hitta några resurser för den angivna kulturen (eller den neutrala kulturen) i den aktuella sammansättningen. Kontrollera att strings.Resource.resources har bäddats in i eller länkats till sammansättningen WindowsApplication1 korrekt.
baseName: strings.Resource locationInfo: <null> resource file name: strings.Resource.resources assembly: WindowsApplication1, Version=1.0.1535.20080, Culture=neutral, PublicKeyToken=null
</code>
Jag gör väll galet någonstans, men var??Sv: Flerspråks-stöd
Det exception du får innebär att ResourceManagern inte kan localisera
din resurs i din assembly, sannolikt är namnet du ger fel.
Det enklaste sättet att undersöka detta är att kontrollera två saker:
1. Öppna din assembly med Ildasm och undersök vad din resurs verkligen heter.
Det ska se ungefär så här ut;
.mresource public DefaultNamespace.ResourceName.bmp
{
}
(ovanstående fall är en bitmap som inbäddad resurs)
2. Kolla under projekt properties och default namespace, detta kommer
att appendas till namnet på din resurs när den kompileras in i dllen
DanielSv: Flerspråks-stöd
Du har gjort helt rätt, dock en sak.
ResourceManager resourceManager = new ResourceManager("strings.Resource",
du måste ange Namespacet i denna.
Låt säga att du har Namespace Foo
då blir sökvägen till till resurs. Foo.strings observera att du inte har med din endelse. I ditt fall heter dina filer resx och inte resource, Det var mer ett exempel som jag angav.
Så ändra till <namespace>.string så skall allt gå bra. Om du exempelvis skulle skapa en undermapp i ditt projekt låt säga images, då måste du ange <namespace>.<mapp>.strings
Du måste inte ha med den där Name variablen, jag la bara till den för att göra det lite tydligare, du kan skriva namnet direkt i GetString.... Metoden...
<code>
ResourceManager resourceManager = new ResourceManager("<namespace>strings",Assembly.GetExecutingAssembly());
String ResourceResult = resourceManager.GetString("string1");
MessageBox.Show(ResourceResult);
</code>
Mvh JohanSv: Flerspråks-stöd
Nu har det lyckats.
Jag skriver in lösningen här, för att andra skall kunna se:
<code>
//måste ha med
using System.Globalization;
using System.Threading;
using System.Resources;
using System.Reflection;
private ResourceManager rm;
// min namespace är namespace WindowsApplication1
//jag har två resoursefiler
//strings.en.resx
//strings.sv.resx
rm = new ResourceManager("WindowsApplication1.strings", this.GetType().Assembly);
MessageBox.Show(rm.GetString("txtWelcomme"));
</code>
Detta fungerar nu 100% perfekt, tack för denna hjälp.
Nu problem nr 2.
Om jag skriver
<code>
System.Threading.Thread.CurrentThread.CurrentUICulture= new System.Globalization.CultureInfo("en-US");
</code>
..innan jag laddar formuläret, så kan jag ju styra språket, men jag skulle vara intreserad av att kunna ändra via en listbox, hur i hela fridens namn gör jag det???Sv: Flerspråks-stöd
du skapar upp de culturer du vill tillåta i en listbox, plockar ut dess seleced item och lägger den i en variabel som du sätter i den kod där du nu hårdkodat kulturen...
är du med?
1... Skapa ListBox med det värden du vill ha, plocka ut selectedItem
<code>
System.Threading.Thread.CurrentThread.CurrentUICulture= new System.Globalization.CultureInfo(< sätt slected Item här >); '<------------------
</code>
Mvh JohanSv: Flerspråks-stöd
Hur kommer jag åt kontrollerna i de övriga formulären från mitt main formulär ?
Om jag tex. väljer engelska som språk så vill jag ju att alla lables och knappar mm ska ändra språk. Kommer inte åt dom från min main. Ska man ändra dessa i själva händelsen eller räcker det man gör det när man laddar resp form, kollar vilket språk alternativ som är checked.Sv: Flerspråks-stöd
Jag har lagt in tre item i en combobox
Svenska
Engelska
Tyska
Sen försöker jag så här:
<code>
private void comboBox1_SelectedIndexChanged(object sender, System.EventArgs e)
{ // sv-SE en-US
string country="";
switch(comboBox1.SelectedIndex)
{
case 0:
country ="sv-SE";
break;
case 1:
country ="en-US";
break;
case 2:
country ="nl-NL";
break;
}
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(country);
}
</code>
Och nu händer det.......absolut ingenting.
Jag måste ha missförståt dig på något sätt, men kan man inte göra så här?
[RÄTTELSE]
Resurce filen fungerar, dvs genom att ändra i listboxen så får jag appen att ändra språk, men FORMEN ändra inte språk, förstår du hur jag menar???Sv: Flerspråks-stöd
inte ska det vara lätt när det kan vara svårt...Sv: Flerspråks-stöd
på din Tråd så finns det förutom en CurrentCulture property även en CurrentUiCulture.
saxat från msdn:[C#]
public CultureInfo CurrentUICulture {get; set;}
det är denna som styr vilken kultur som ditt gränssnitt exekverar under!Sv: Flerspråks-stöd
<code>
using System.Security.Permissions;
[assembly:SecurityPermission( SecurityAction.RequestMinimum, ControlThread = true )]
Thread.CurrentThread.CurrentCulture = new CultureInfo( country, false );
</code>
När jag sökte på public CultureInfo CurrentUICulture {get; set;} så var det detta jag fick fram, men inte hjälpte det.
Jag kan nog inte ritigt förstå hur du menar.Sv: Flerspråks-stöd
Sv: Flerspråks-stöd
Jag har lagt ut några knappar, och skrivit in på Svenska och på Engelska, genom att i porteties ändrat språk.
Jag har ju dessutom lagt till två resursfilerna plus en combobox med de olika språken.
Vad som händer är, att om jag ändra språk via comboboxen so kan jag få de olika resurcefilerna, det fungerar perfekt, men jag kan inte få knappar labeller att pyta språket, när jag ändrar i comboboxen.
Har du löst det?Sv: Flerspråks-stöd
tex:
<code>
private void button1_Click(object sender, System.EventArgs e)
{
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
this.button2.Text = resources.GetString("button2.Text");
}
</code>
Om du tar och klipper ut all kod som finns i Initialize i din Form och kopierar in det i en ny metod. Se till så kontrollers event samt att nya kontroller inte skapas på nytt. Sedan när du sätter om till ett annat språk så anropar du din nya metod. Det löser problemet. Du skulle säkert göra ett hack i Initilize metoden och anropa den på nytt, problemet är att Initialize är genererat av VS.Net och kan förändras om du lägger till nya kontroller etc.
/Fredrik NorménSv: Flerspråks-stöd
Det betyder ju t ex att tooltips måste läggas in för varje kontroll:
<code>
this.toolTip1.SetToolTip(this.button4, resources.GetString("button4.ToolTip"));
</code>
Men hur gör man med t ex comboboxen?
I initcoponent så ser det ju ut så här:
<code>
this.comboBox1.Items.AddRange(new object[] {
resources.GetString("comboBox1.Items"),
resources.GetString("comboBox1.Items1"),
resources.GetString("comboBox1.Items2")});
</code>
...eller måste man köra ett casefall?
[REDIGERAT]
Dumt av mig, det vr ju bara att klistra in ovanstående.
Tack alla för hjälpen, nu fungerar det.Sv: Flerspråks-stöd
Sätt localized till true på din form. Då skapas en resource manager automatiskt.
Utveckla hela applicationen i det neutrala språket. Välj det srpåk du vill översätta till och ändra sen i ui:et. Studio klarar själv av att skilja på de olika språken och sparar
därför informationen på olika platser.
Uppfinn INTE hjulet gång efter gång efter gång ...
Läs mitt tidigare inlägg på samma ämne!!!
DanielSv: Flerspråks-stöd
Han gör precis som du säger, dock så vill han ändra spårket under runtime till ett annat spårk, detta går dock inte genom att enbart sätta om trådens currentUIculture. Det går första gången då applikationen laddas, resursen och språksträngarna etc hämtas och placeras ut i Initialize... Men görs som sagt inte automatikst när trådens currentUIculture ändras, resursen etc måste laddas om på nytt.
/Fredrik Normén NSQUARED2Sv: Flerspråks-stöd
Sv: Flerspråks-stöd
Med tanke på att jag har löst mitt problem, vad är det som inte fungerar för dig?Sv: Flerspråks-stöd
Sv: Flerspråks-stöd
Sv: Flerspråks-stöd
Det kanske är bättre att ha nån annan klass som skickar t.ex. ett languagechanged event eller nåt som varje formulär kan lyssna på. Annars måste ju hela tiden en form känna till vilka kontroller en annan form har. Alternativet är ju att du i varje form implementerar nån publik metod (kanske från ett interface) som ändrar språket på alla kontrollerna i just det formuläret.
lite tdéer iallafalllSv: Flerspråks-stöd
Skulle jag inte bara kunna skapa en public metod som jag kör override på i varje formulär?
/ MartinSv: Flerspråks-stöd
Problemet är ju bara att du hela tiden då måste hålla reda på vilka formulär som du har. Om du har en klass som skickar ett event, och alla formulär eller klasser som du vill att man skall kunna byta språk på, lyssnar på det eventet. Då behöver den klassen inte känna till vilka som det skall bytas språk på men varje grej som skall byta språk måste känna till språkbytaren... (är det nån som fattar nåt? ;-) )
Alltså, jag skulle nog kört på event-grejen, känns som att det blir lättare att underhålla istället för att nån skall känna till alla dina formulär...