Multilanguage WPF Application - c#

I'm working multi-language (Arabic & English)
WPF application with resources in two different files (Resources.en-GB & Resources.ar-LY),
I declared a new method in the app.xaml
public void LanguageSwitcher(string _currentUICulture)
{
System.Threading.Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo(_currentUICulture);
}
In the MainWindow and after Initialize Component I put
((App)Application.Current).languageSwitcher("ar-LY");
this.FlowDirection =
CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft ?
FlowDirection.RightToLeft :
FlowDirection.LeftToRight;
In the language switcher button, I call the method and pass the en-GB culture that I want
((App)Application.Current).languageSwitcher("en-GB");
The Problem: When I hit the language button to change UI to English, The culture changed and the window flow direction changed to LeftToRight BUT the text does not change, It seems that the Resources.en-GB does not load!
What I miss here?!

You need to reload every label component after changing the culture.
You can try to open new window after changing the culture and check that the created components are changed.

Related

Attempted Localization Always Shows English on Windows Form App

I am trying to set up a Windows Form login screen that uses the user's language to set either German or English for a class. I have set up my .resx files within the Properties of my project, but I cannot figure out why the form always shows in English.
I reviewed How to use localization in C# and How to make multi language app in winforms, which is where I found the information on setting up the Strings.resx and Strings.de.resx files, but the text when I set my UI Language to German always shows in English. On the LoginForm Properties, I have Localizable set to True.
As I want the app to load the screen with the correct language, I placed all my code in the Load Event:
private void LoginForm_Load(object sender, EventArgs e)
{
// Check system language
CultureInfo Language = CultureInfo.CurrentUICulture;
// Check if system language is set to German or English, and display
// login screen elements as appropriate
if (Language.Name.ToString() == "Deutsch")
{
LoginLabel.Text = Properties.Strings.LoginLabel;
UserLabel.Text = Properties.Strings.UserLabel;
PasswordLabel.Text = Properties.Strings.PasswordLabel;
LoginButton.Text = Properties.Strings.LoginButton;
ExitButton.Text = Properties.Strings.ExitButton;
}
}
I know I'm likely missing something simple, but I can't figure it out. If I need to, I can manually set the Text fields to the German version, but I'd rather have it separated in the .resx files if possible.
Changed Language to a string, and removed the if loop, and it's now appearing in German when set that way.

Localisation via resx in winforms

There are many questions about it but still haven't read a solution for me
I have all my resources in a seperate project and this project has a Resource folder with 3 languages in it.
In any control I have in the constructor a call to InitializeLanguage()
where I set the right text for the right language like this:
public void InitializeLanguage()
{
bOK.Text = Lastenboek.Language.Ok;
cbSM.Text = Lastenboek.Language.SamenvattendeMeetstaat;
cbDM.Text = Lastenboek.Language.DetailMeetstaat;
cbDMHeadingStyles.Text = Lastenboek.Language.KopStijlen;
cbExportArtikelsZonderMeetstaat.Text = Lastenboek.Language.ArtikelsZonderMeetstaat;
cbSMHeadingStyles.Text = Lastenboek.Language.KopStijlen;
cbRamingsPrijs.Text = Lastenboek.Language.Ramingsprijs;
cbBeknopteOmschrijving.Text = Lastenboek.Language.BeknopteOmschrijving;
cbFaseSM.Text = Lastenboek.Language.GesplitstOpFase;
groupBox3.Text = Lastenboek.Language.Filter;
label2.Text = Lastenboek.Language.Tot;
label1.Text = Lastenboek.Language.DatumVan;
gbPrijzen.Text = Lastenboek.Language.Prijzen;
label3.Text = Lastenboek.Language.Account;
cbTotaalSM.Text = Lastenboek.Language.Totaal;
groupBox4.Text = Lastenboek.Language.Template;
label4.Text = Lastenboek.Language.Layout;
Text = Lastenboek.Language.ExporteerMeetstaat;
}
Everything works fine but now sometimes the label is too small for the text in other languages. Is there a good way to change the language at designtime and change the dimensions for different languages?
Yes. And you don't even need to programmatically set localized texts/images and other values.
Just set Localizable property on your form to true and then you can switch languages at design time and edit everything for that language at design time.
When you start the application the form will use the Windows language. If you want to change it programmatically just set Thread.CurrentThread.CurrentUICulture property. You might want to repoen your form to apply the language or call InitializeComponent() explicitly.
The problem is that you have dynamic texts for controls, but you want to have "hardcode" fixed control sizes for every language.
with this approach maintaining can be complicated. Every change in translation should be tested in UI - is it fit or not in the control.
Another approach will be support "AutoSize" for controls. Winforms have TableLayoutPanel control, which can be useful for controls with dynamic texts.

How to set two different Cultures for two different Controls on a single Form at the same time?

I need to show an demo of how the control can be localized using the satellite assemblies. While doing this I have stuck with one place where i have two controls on a form both are same. I used to derive it from the Label.
Now I need to display the control1 with culture fr-FR and control2 with the culture de-DE.
Is there any options is available to set different cultures for the same controls that displayed in a form.
The following screenshot will show my need.
Please suggest me is that possible or not. If its possible, let me know how can I achieve this.
You can rely on localization feature of windows forms. This way you can setup your controls with different properties for different cultures. Then you can show the whole form with properties set for a specific culture.
Also you have option to show each control with a different culture. To do so it's enough to use such code in your form Load event handler:
System.Threading.Thread.CurrentThread.CurrentUICulture =
System.Globalization.CultureInfo.GetCultureInfo("fr-FR");
var resources = new System.ComponentModel.ComponentResourceManager(this.GetType());
resources.ApplyResources(button1, button1.Name);
And simply for button2 use above code with de-DE culture.
Note
Above solution is not limited to Text property, it supports all Localizable properties.
You can simply make it as an extension method for control class.
It has designer-support for creating localized appearance of your controls.
Try to use Following code.
if(langCode=="fr-FR")
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("fr-FR");
}
if(langCode=="de-DE")
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE");
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("de-DE");
}
Because you want to demonstrate localization feature for your application you can change current thread culture when you updating value for your control
private void SetLocalizedTextForLabel(Label label, string language)
{
var original = Thread.CurrentThread.CurrentUICulture;
Thread.CurrentThread.CurrentUICulture = new CultureInfo(language);
// Here value will be retrieved from YourResource based on the current culture
label.Text = Properties.YourResource.YourText;
Thread.CurrentThread.CurrentUICulture = original;
}
Then use it
SetLocalizedTextForLabel(frenchLabel, "fr-FR");
SetLocalizedTextForLabel(germanLabel, "de-DE");

Globalizing application dynamically

In My application I have 2 Resource dictionaries (Spanish and English) that contains all strings of the application. In the main window I have a combobox from where the user can select their desired language. What I wanted to do is, when the user clicks on a specified language it should change the language of the entire application, not just the current window. I have searched here for a simple solution but couldn't find any. Can anyone suggest a way to achieve this?
Currently I use this way to change the current form's language
on the combobox selection changed event
private void Language_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ResourceDictionary dictionary = new ResourceDictionary();
string lang = e.AddedItems[0].ToString();
dictionary.Source = new Uri(#"/Resources/Languages/"+lang+".xaml", UriKind.Relative);
Application.Current.Resources.MergedDictionaries.Clear();
Application.Current.Resources.MergedDictionaries.Add(dictionary);
}
PS: I don't want to close and re open the window to the changes to be applied
The WPF Localization Extension provides on-the-fly language changing without restarting the application.
Please note, that this approach uses *.resx-files for localization and not WPF specific ResourceDictionaries.
You can follow the common guides on the link above. Additionally, you can read through this guide.

Make user control display outside of form boundry

I've decided to reimplement the datetime picker, as a standard datetime picker isn't nullable. The user wants to start with a blank field and type (not select) the date.
I've created a user control to do just that, but if the user control is near the edge of the form, it will be cut off on the form boundry. The standard datetime picker doesn't suffer from this problem.
Here is a picture showing the problem. My user control is on the left, the standard datetimepicker is on the right:
alt text http://img50.imageshack.us/img50/9104/datetimepickervu6.jpg
As you can see, the standard control will display over the form AND application boundry. How do I get the month picker in my control to do the same thing?
Thanks!
The ToolStripDropDown control has this functionallity so by inheriting from it we can make a simple PopupWindow.
/// <summary>
/// A simple popup window that can host any System.Windows.Forms.Control
/// </summary>
public class PopupWindow : System.Windows.Forms.ToolStripDropDown
{
private System.Windows.Forms.Control _content;
private System.Windows.Forms.ToolStripControlHost _host;
public PopupWindow(System.Windows.Forms.Control content)
{
//Basic setup...
this.AutoSize = false;
this.DoubleBuffered = true;
this.ResizeRedraw = true;
this._content = content;
this._host = new System.Windows.Forms.ToolStripControlHost(content);
//Positioning and Sizing
this.MinimumSize = content.MinimumSize;
this.MaximumSize = content.Size;
this.Size = content.Size;
content.Location = Point.Empty;
//Add the host to the list
this.Items.Add(this._host);
}
}
Usage:
PopupWindow popup = new PopupWindow(MyControlToHost);
popup.Show(new Point(100,100));
...
popup.Close();
The screenshots looks like a Windows Forms applications, so my answer is for winforms.
I guess the best solution would be to create a customcontrol that itself uses the datetime picker that already has the behavior.
Show a empty textbox until it gets clicked, then display the datetimepicker.
That would save you a bunch of code..
I ran into this when trying to implement a custom control and discovered that it's a remarkably hard problem. There's no built-in functionality within the Windows.Forms model to support controls whose display area extends outside the client area of their container.
You basically have to either use the Windows API or draw your controls inside a Form with AlwaysOnTop set. Both approaches are harder than they should be. I ended up redesigning my control so that instead of displaying its expanded contents in a dropdown it used a modal dialog. This was a pretty unsatisfying solution, but I spent a couple of weeks trying other approaches and could never get anything that worked consistently across all use cases (like disappearing when the application loses focus).
I'm not 100% sure, but a quick look at the DateTimePicker class on Reflector takes me to the SafeNativeMethods.SetWindowPos internal class.
You can override the SetBoundsCore from the base Control class or, like Tigraine stated, create a custom control based on the DateTimePicker.
Hope it helps,
Bruno Figueiredo
The reason that your control gets chopped off is because it is a child control of the form that you reside on. Any control on the form must be contained by the form, hence it gets chopped off.
I haven't done this in .Net, but had a similar problem in VB6. The solution then was to set the parent of the popup window (the calendar in your case) to be the desktop. This will allow it to extend beyond the boundaries of your form. You'll have to do some P/Invoke magic to find the hWnd of the popup, and another P/Invoke to set the parent.

Categories