Lokalisierung/Mehrsprachige Anwendungen: Zusammengesetzte Phrasen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von tron25.

    Lokalisierung/Mehrsprachige Anwendungen: Zusammengesetzte Phrasen

    Ausgelagert aus Mehrsprachige Anwendung -> Sprache ändern. ~Thunderbolt

    Hallo,

    ich möchte mein Programm nun auch mehrsprachig gestalten. Dazu habe ich diesen und andere Beiträge gelesen. Zu guter Letzt habe ich mir auch den RESX-Manager heruntergeladen und installiert.

    In Visual Studio unterhalb von Extras finde ich auch den RESX-Manager. Leider tut sich nichts, wenn ich ihn aufrufe.

    Was ich (hoffentlich) verstanden und hinbekommen habe, ist, dass ich mehrere Sprachen definieren und die Beschriftungen meiner Elemente anpassen kann. Dazu habe ich die Eigenschaft "Localization" auf "true" gesetzt und "Language" auf "Deutsch (Deutschland)" festgelegt, da meine Programmoberfläche in Deutsch ist. Bitte an dieser Stelle keine Vorträge, dass gute Programme immer in Englisch geschrieben sind und englische Oberflächen haben. Danach habe ich "English" eingestellt und die Beschriftungen der Menüeinträge und Schaltflächen entsprechend umgeschrieben.

    Leider habe ich noch ein Verständnisproblem bei Freitexten. Beispielsweise Folgendes:

    VB.NET-Quellcode

    1. InfoFormular.Text = "HINWEIS"
    2. InfoFormular.Label1.Text = "Die Datei " & Dateiname & " konnte nicht gefunden werden"
    3. InfoFormular.ShowDialog(Me)
    4. InfoFormular.Close()

    Dieser Punkt wurde zwar auch erklärt, aber, wie geschrieben, habe ich da ein kleines Verständnisproblem.

    Kann mir jemand das bitte Schritt für Schritt erklären. Und bitte keine Screenshots, da ich diese aufgrund meiner Blindheit nicht erkennen kann.

    Vielen Dank

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

    @tron25 Sieh Dir mal diesen Thrfead an: Programme mehrsprachig erstellen
    Einen Ressource-Manager habe ich noch nicht benötigt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Verstehe ich das richtig, dass ich, wie in dem verlinkten Beispiel die Resoursendateien "Resources.de-DE.resx" und "Resources.en-us.resx" erstelle, sie umkopiere, die entsprechenden Verknüpfungen anpasse und jede Meldung, die ausgegeben werden soll, einer Variablen zuweise und in die entsprechenden Resoursendateien in den entsprechenden Sprachen eintrage, um sie dann bei bedarf über den Variablennamen àufzurufen?

    Bei der Weitergabe des Programms sollten die Sprachdateien aus dem Debug-Verzeichnis mitgegeben werden. Wie sieht das mit den Dateien in "My Project" aus? Werden diese automatisch in die .Exe kompiliert oder müssen diese ebenfalls manuell mitgegeben werden?

    ----------

    Ich habe folgende Beispiele gefunden, mit denen zur Laufzeit die Sprache geändert werden soll, ohne das Programm mit "application.restart()" neu starten zu müssen.

    VB.NET-Quellcode

    1. Private Sub EnglischMenue_Click(sender As Object, e As EventArgs) Handles EnglischMenue.Click
    2. SpracheAendern("Englisch")
    3. End Sub
    4. Private Sub SpracheAendern(Sprache As String)
    5. Select Case Sprache
    6. Case "Deutsch"
    7. System.Threading.Thread.CurrentThread.CurrentUICulture = New System.Globalization.CultureInfo("de")
    8. Controls.Clear()
    9. Events.Dispose()
    10. InitializeComponent()
    11. Case "Englisch"
    12. System.Threading.Thread.CurrentThread.CurrentUICulture = New System.Globalization.CultureInfo("en")
    13. Controls.Clear()
    14. Events.Dispose()
    15. InitializeComponent()
    16. End Select
    17. End Sub


    Tatsächlich werden die Beschriftungen geändert. Allerdings wird das Formular nach dem Befehl

    VB.NET-Quellcode

    1. InitializeComponent()

    unsichtbar. Das Programm läßt sich aber weiterbedienen. Andere Formulare, die aufgerufen werden, sind sichtbar. Da ich einen Screenreader verwende, kann ich weiterarbeiten. Die Sprachausgabe liest mir alle Menüpunkte und anderen Elemente vor, obwohl die Oberfläche unsichtbar ist. Auch ein Maximieren des Fensters bringt keinen Erfolg.

    Gibt es eine andere Möglichkeit zu "InitializeComponent()"? Bzw. Was kann ich noch tun, damit die Oberfläche nach diesem Befehl wieder sichtbar wird?

    Vielen Dank schon mal im Voraus

    Code-Tag korrigiert. ~Thunderbolt

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Thunderbolt“ ()

    tron25 schrieb:

    und jede Meldung, die ausgegeben werden soll, einer Variablen zuweise
    Für jede Meldung wird ein lokalisierbarer Ressourcen-Eintrag generiert.
    Das Umkopieren von RESX-Dateien kommt bei mir nicht vor. Was meinst Du damit?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe den Beitrag

    "Programme mehrsprachig erstellen"

    gelesen. Dort steht u.a.:

    "Nun zu den Texten, Bildern usw., die aus der Ressource geladen werden.
    Wir fügen mit Projekt -> Hinzufügen -> neues Element eine neue Ressourcendatei hinzu, der wir den Namen Resources.de-DE.resx geben.
    ==> Die korrekte Bezeichnung für andere Sprachen entnehmt einer vom System erstellten anderssprachigen Dialog-Ressource. <==
    Nun müssen wir das Projekt mal kurz beenden, um die neue Ressourcen-Datei im Explorer von Hand richtig einzusortieren.
    Wir verschieben die Datei Resources.de-DE.resx in das Unterverzeichnis My Project\. Außerdem öffnen wir die Datei MEIN_PROJEKT.vbproj im Editor, suchen den Text Resources.de-DE.resx und machen daraus My Project\Resources.de-DE.resx"

    So, wie ich es verstanden habe, dienen die neu erstellten Dateien für Texte, die zur Laufzeit generiert werden, wie z.B. Fehlermeldungen oder Hinweise.

    tron25 schrieb:

    So, wie ich es verstanden habe, dienen die neu erstellten Dateien für Texte, die zur Laufzeit generiert werden, wie z.B. Fehlermeldungen oder Hinweise.
    Ja.
    Texte, die an der GUI angezeigt werden sollen, werden in die entsprechenden Controls eingetragen,
    Texte, die z.B. in MessageBoxen angezeigt werden, werden in die entsprechende Ressource-Text-Tabelle eingetragen.
    Wo ist das Problem?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das mit den externen Dateien habe ich vermutlich verstanden. Mein Problem ist, dass das Programm nach
    [vbnet]
    InitializeComponent()
    {/vbnet]
    unsichtbar wird und bleibt. Lediglich ausgeklappte Menüpunkte werden sichtbar.

    Was kann ich tun, damit die Oberfläche wieder angezeigt wird?

    tron25 schrieb:

    unsichtbar wird und bleibt.
    Poste mal die komplette Form oder ggf.das Projekt.
    Überzeuge Dich davon, dass das, was Du postest, Deinen Effekt reproduziert.
    Schreib dazu, was zu tun ist, um Deinen Effekt zu reproduzieren.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe das auch einmal versucht. Aber je größer eine Anwendung wird, desto unübersichtlicher wird alles. In der IDE sieht man nicht sofort welcher String welchen Wert hat und das ganze ist dann schon sehr mühsam. Ich hatte das mal in einer Kassensoftware versucht, dann aber mangels qualitativ passender Übersetzer nach ein paar Jahren aufgegeben und alles auf fixe deutschsprachige Strings umgeschrieben. Kein Problem, weil die Ausrichtung nur auf DACH ist.

    Meine aktuelle Anwendung bopv.info habe ich in deutsch und in englisch geschrieben.
    Die Anwendung selbst ist sehr überschaubar und weitere Sprachen sind nicht geplant.
    Daher habe ich in jeder Form beim laden einfach eine Select Case Abfrage installiert um die Oberfläche zu benennen.
    Im Quellcode arbeite ich dann ebenfalls mit Select case oder If Then Abfragen.

    Bei größeren Projekten würde ich mir das aber so nicht mehr zutrauen.

    VB.NET-Quellcode

    1. Private Sub SetSprache()
    2. Select Case My.Settings.Sprache
    3. Case 0
    4. Me.Text = "BOPV.Info - myStrom Switch / Shelly Plug S"
    5. Label_apisettings.Text = "WIFI Power Switch API settings"
    6. Label_IPAddress.Text = "Local IP address:"
    7. CheckBox_myStromActive.Text = "activate switch logic control"
    8. Label_logic.Text = "Switching logic dependent on the energy surplus"
    9. Label_Loadfrom.Text = "Charging from:"
    10. Label_bis.Text = "to:"
    11. Label_Leistung.Text = "Power consumption:"
    12. Label_Hausreserve.Text = "House consumption:"
    13. Button_Test.Text = " Get consumption data"
    14. Button_Einschalten.Text = " Switch on"
    15. Button_Ausschalten.Text = " Switch off"
    16. Button_Save.Text = " save and restart"
    17. Label_Modell.Text = "Switch type:"
    18. Case 1
    19. Me.Text = "BOPV.Info - myStrom Switch"
    20. Label_apisettings.Text = "WIFI Power Switch API Einstellungen"
    21. Label_IPAddress.Text = "Lokale IP-Adresse:"
    22. CheckBox_myStromActive.Text = "aktiviere Switch Logik"
    23. Label_logic.Text = "Schaltlogik abhängig vom Energieüberschuss"
    24. Label_Loadfrom.Text = "Ladezeiten von:"
    25. Label_bis.Text = "bis:"
    26. Label_Leistung.Text = "Leistung Verbraucher:"
    27. Label_Hausreserve.Text = "Haus Grundverbrauch:"
    28. Button_Test.Text = " Verbrauchsdaten abfragen"
    29. Button_Einschalten.Text = " einschalten"
    30. Button_Ausschalten.Text = " ausschalten"
    31. Button_Save.Text = " speichern && neu starten"
    32. Label_Modell.Text = "Switch Modell:"
    33. End Select
    34. End Sub


    VB.NET-Quellcode

    1. If My.Settings.Sprache = 0 Then sprachform_Temp = "Total to grid" Else sprachform_Temp = "Gesamt ins Netz"
    2. With ListView_DeviceData.Items.Add(sprachform_Temp)
    3. .UseItemStyleForSubItems = False
    4. .SubItems.Add(PowerSensor_active_cap + " kWh")
    5. .SubItems.Add("")
    6. .SubItems.Add("")
    7. For z As Integer = 1 To 3
    8. .SubItems(z).ForeColor = Color.DeepSkyBlue
    9. Next z
    10. End With
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

    dive26 schrieb:

    In der IDE sieht man nicht sofort welcher String welchen Wert hat und das ganze ist dann schon sehr mühsam.
    Wenn Du das Studio korrekt bedienst, kommen da schon korrekte Hinweise.
    Einmal bei der Eingabe, zum anderen bei HOver:



    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Jetzt habe ich eine kleine Anwendung geschrieben. Das Formular enthält eine Menüleiste mit dem Menüpunkt "Datei". Dieser hat die Menüpunkte "Deutsch", "Englisch" und "Beenden". Alles funktioniert so, wie es soll.

    Wenn ich mein eigentliches Programm einzelschrittweise laufen lasse, so bekomme ich an der Stelle

    VB.NET-Quellcode

    1. )
    2. InitializeComponent()
    3. {/vbnet]
    4. folgende Meldung:
    5. [vbnet]
    6. Aufgrund Ihrer Einzelschrittanforderung wurde eine Eigenschaft oder ein Operator automatisch übersprungen.
    7. Dieses Verhalten kann im Kontextmenü für die ausgeführte Zeile überschrieben werden. Wählen Sie dazu entweder "Einzelschritt in Angabe" aus, oder deaktivieren Sie die Option "Eigenschaften und Operatoren überspringen (nur verwaltet)".
    8. Möchten Sie bei automatisch übersprungenen Elementen weiterhin benachrichtigt werden?

    Ich finde die genannten Einstellungen nicht. Ich habe in den Projekteigenschaften nachgesucht.

    Die gleiche Meldung bekomme ich auch, wenn ich das neue Programm schrittweise ausführe. Allerdings bleibt die Oberfläche danach sichtbar.

    Nun werde ich mal aus dem großen Programm Element für Element aus dem Hauptformular in das neue Programm hinzufügen und schauen, wann die Oberfläche nicht mehr angezeigt wird.
    @tron25 Es genügt, wenn Du dann das bereinigte Projekt (ohne bin-, obj- und .vs-Verzeichnisse) in eine ZIP packst und anhängst.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @tron25 Hast Du Dich davon überzeugt, dass der beschriebene Effekt mit Deinen hochgeladenen Quellen bei Dir reproduziert wird?
    Was muss ich tun, um den von Dir beschriebenen Effekt zu reproduzieren?
    ====
    Ich weiß nicht, wo Du den Unfug her hast, die Sprache per InitializeComponent()[tt] zu ändern. Nach dem Ändern der Sprache lässt sich Dein Programm leider nicht mehr per [tt][X] beenden.
    In meinem oben verlinkten Thread im 3. Post habe ich eine Methode vorgestellt, das ganze per Settings-Eintrag und Application.Restart() löst. Das funktioniert sauber.
    Programme mehrsprachig erstellen

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    ich könnte mir sprichwörtlich in meinen Allerwertesten beißen. Der Grund, warum es nicht ging war Folgender:
    Das Programm startet mit einer Introanimation. Wenn diese abgelaufen ist, wird das Introformular genauso schnell unsichtbar gemacht, wie das eigentliche Programmformular sichtbar. Wenn der Benutzer allerdings in den Einstellungen festgelegt hat, dass kein Intro angezeigt werden soll, so wird das Programmformular auf einen Schlag sichtbar gemacht. Das hatte ich übersehen. Ich muß nach dem Initialisieren einfach die Zeile

    VB.NET-Quellcode

    1. Me.Opacity = 1

    hinzufügen.

    Allerdings gibt es da noch ein weiteres Problem. Die "KeyPreview"-Eigenschaft des Formulares ist auf "True" gesetzt, damit Tastendrücke abgefangen und ausgewertet werden können. Auch, wenn ich diese Eigenschaft nach dem Initialisieren auf "True" setze, funktionieren Tastendrücke nicht. Befehle, die in den Menüpunkten stehen, werden allerdings ausgeführt.

    Woran könnte es liegen, das Tastendrücke nach der Neuinitialisierung nicht mehr erkannt werden?
    Definiere

    tron25 schrieb:

    Neuinitialisierung
    Wenn Du damit den Aufruf von InitializeComponents() meinst, bin ich draußen, weil ich keine Kust habe, Deinen falschen Quereinstieg zu bearbeiten.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo

    ich habe mir Einiges zum Thema "Mehrsprachige Programme" durchgelesen. Dann habe ich mein Programm folgendermaßen angepaßt:
    1. Das Formular lokalisierbar gemacht und eine zweite Sprache eingestellt.
    2. Alle Menüpunkte in die zweite Sprache umbenannt.
    3. Die entsprechende Resoursendatei erstellt und in das Verzeichnis "My Project" kopiert.
    4. Den entsprechenden Eintrag in der .vbproj geändert.
    5. Einträge in der Standard- und in der neuen Resoursendatei erstellt.
    6. Eine Routine zum ermitteln der eingestellten Sprache geschrieben.

    Bis hier hin funktioniert alles. Allerdings habe ich nicht verstanden, wohin ich die Routine schreiben muß, damit sie als aller Erstes ausgeführt wird. Ich habe was von einer New-, Main- und auch einer MyApplication_Startup-Funktion gelesen. In einer der letzten Beiträge dieses Themas wird auch ein Beispiel in einem Modul gezeigt. Wenn ich dieses Beispiel nachprogrammiere und einen Haltepunkt setze, hält das Programm aber nicht dort an.

    Mein Programm bezieht seine Variablen aus einer INI-Datei. In dieser gibt es auch eine Zeile mit der eingestellten Sprache. Nicht wundern, da die Datei Benutzerfreundlich sein soll, stehen die Sprachen ausgeschrieben darin. In der entsprechenden Funktion werden dann die Kürzel daraus.
    Hier meine Funktion:

    VB.NET-Quellcode

    1. Private Sub New()
    2. Dim Sprache As String = "Deutsch"
    3. Dim Culture As System.Globalization.CultureInfo
    4. Dim INIDatei As String
    5. Dim Userverzeichnis As String = My.Computer.FileSystem.SpecialDirectories.MyDocuments
    6. Dim Dateiinhalt As System.IO.StreamReader
    7. Dim AktuelleZeile As String
    8. Dim X As Integer
    9. INIDatei = Userverzeichnis & "\PunktBilder\PunktBilder.ini"
    10. If My.Computer.FileSystem.FileExists(INIDatei) Then
    11. Dateiinhalt = New StreamReader(INIDatei)
    12. Do Until Dateiinhalt.EndOfStream
    13. AktuelleZeile = Dateiinhalt.ReadLine
    14. If AktuelleZeile.Substring(0, My.Resources.Programmsprache).ToUpper = My.Resources.Programmsprache.ToUpper Then
    15. X = My.Resources.Programmsprache.Length + 1
    16. Do Until X >= AktuelleZeile.Length
    17. If AktuelleZeile.Substring(X, 1) <> " " Then
    18. Exit Do
    19. End If
    20. X += 1
    21. Loop
    22. If X < AktuelleZeile.Length Then
    23. Sprache = AktuelleZeile.Substring(X, AktuelleZeile.Length - X)
    24. End If
    25. Exit Do
    26. End If
    27. Loop
    28. Select Case Sprache.ToUpper
    29. Case "DEUTSCH"
    30. Sprache = "de"
    31. Case "ENGLISH"
    32. Sprache = "en"
    33. End Select
    34. Culture = New System.Globalization.CultureInfo(Sprache)
    35. System.Threading.Thread.CurrentThread.CurrentUICulture = Culture
    36. End If
    37. End Sub


    Vielleicht wurde die richtige Lösung auch schon in einem der gepoasteten Bilder dargestellt.
    Hat jemand eine Idee, die ich auch nachvollziehen kann? Bitte Beispiele nicht als Bild anhängen, da ich blind bin und diese nicht erkennen kann.

    Danke
    @tron25 Projekt => Eigenschaften => Anwendung => [Anwendungsereignisse anzeigen]
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Scheint zu funktionieren. Vielen dank.

    Für die, die es interessiert, hier die entsprechende Funktion:

    VB.NET-Quellcode

    1. Private Sub Programmstart() Handles Me.Startup
    2. Dim Sprache As String = "Deutsch"
    3. Dim Culture As System.Globalization.CultureInfo
    4. Dim INIDatei As String
    5. Dim Userverzeichnis As String = My.Computer.FileSystem.SpecialDirectories.MyDocuments
    6. Dim Dateiinhalt As System.IO.StreamReader
    7. Dim AktuelleZeile As String
    8. INIDatei = Userverzeichnis & "\PunktBilder\PunktBilder.ini"
    9. If My.Computer.FileSystem.FileExists(INIDatei) Then
    10. Dateiinhalt = New System.IO.StreamReader(INIDatei)
    11. Do Until Dateiinhalt.EndOfStream
    12. AktuelleZeile = Dateiinhalt.ReadLine
    13. If AktuelleZeile.Length >= 16 Then
    14. If AktuelleZeile.Substring(0, 16).ToUpper = "PROGRAMMSPRACHE:" Then
    15. Sprache = "Deutsch"
    16. Exit Do
    17. End If
    18. End If
    19. If AktuelleZeile.Length >= 17 Then
    20. If AktuelleZeile.Substring(0, 17).ToUpper = "PROGRAM LANGUAGE:" Then
    21. Sprache = "English"
    22. Exit Do
    23. End If
    24. End If
    25. Loop
    26. Dateiinhalt.Close()
    27. Select Case Sprache.ToUpper
    28. Case "DEUTSCH"
    29. Sprache = "de"
    30. Case "ENGLISH"
    31. Sprache = "en"
    32. End Select
    33. Culture = New System.Globalization.CultureInfo(Sprache)
    34. System.Threading.Thread.CurrentThread.CurrentUICulture = Culture
    35. End If
    36. End Sub

    Da ich zu Beginn noch nicht weiß, in welcher Sprache die INI-Datei geschrieben ist, muß ich auf etwas umständliche Weise alle Sprachen, in die das Programm übersetzt wurde prüfen und so die einzustellende Sprache herausfinden.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „tron25“ ()