Globalizing application dynamically - c#

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.

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.

Inherit properties to a WPF Page element

This may be a very simple question, so my apologies.
My problem here is that I want to build a Multilingual WPF App using C#, but I don't know how to make my different Page elements inherit the same method which makes my MainWindow translate to different languages. The app is done, I'm just translating it to English (My native language is Spanish).
I'm using Resource files to translate it.
Code for the language translation:
private void Languages_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
//This is the combobox in which you select the language to display the app in
Set_Language();
}
//This is the method to invoke the Resource Manager and all the stuff from the resource file.
private void Set_Language()
{
if (!boolInit)
{
strLanguage = "LeitProjekteV2._0.Languages." + ((ComboBoxItem)LanguageSel.SelectedItem).Name.ToString();
ResourceManager LocRm = new ResourceManager(strLanguage, typeof(MainWindow).Assembly);
//Menu buttons
lblMenu.Content = LocRm.GetString("strMainMenu"); //The names inside the "" are the names of the resource in the Resource file which, depending on the language selected(Spanish, English and German)
//Change the text of whatever I choose; in this case, a Label named 'lblMenu'
MapButt.Content = LocRm.GetString("strMapButt");
BuscButt.Content = LocRm.GetString("strBusButt");
AgeButt.Content = LocRm.GetString("strAgeButt");
ComButt.Content = LocRm.GetString("strComButt");
InfButt.Content = LocRm.GetString("strInfButt");
LoginButt.Header = LocRm.GetString("strLoginButt");
RegisterButt.Header = LocRm.GetString("strRegisterButt");
ContacButt.Header = LocRm.GetString("strContacButt");
MasButt.Header = LocRm.GetString("strMoreButt");
//Here go the names of everything the Pages contain that I want to translate, just like above
//Have no idea how to inherit this method to all the pages
}
}
Now, I have several pages embedded in the same MainWindow.xaml, so that you click the button "Map", a Frame changes it's content to a Page named Map.xaml, and so on for other buttons.
But how do I make those Pages also translate?
Since the Set_Language() method takes the string value of the Combobox in order to select the correct Resource File, I don't want to create one combobox for every Page that I have, albeit that would eliminate my problem.
Any help? Sorry for the horrible way of asking, I'm still getting the hint here.
Thanks.
Use the below:
var wnd = Window.GetWindow(this); //get current window
Cast it to your window class and expose your language as a public property
Use your page to get the property by finding the current window
You may create a parent page class that do the above, and inheriting it for all your pages so you dont repeat code
I can see the difficulty you are facing is that you can't find a way to share the combobox across the main window and the pages hosted in the frame.
You can set a global variable that is accessible from the whole application, a good place is in application settings. Then when you make a selection with the Combobox, you just update the selected value to that variable.
Then call each page's Set_Language() method when they are being loaded into the Frame. In the Set_Language() method of each page, you can query what is been set to the variable stored in the application settings.
If you want to quick solution, create a static class to hold the selected language is also OK.
static class UserSelections
{
public static string Language { get; set; }
}

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.

c# - How to access a variable from outside its class in a method in some other class?

I am a beginner in c# programming and I am developing windows phone application after reading some tutorials.
My idea is when the user clicks a button in a windows page, some other button in other windows phone page must change color from red to green.
Pardon me if I am too Basic.
This I have defined in a page named "IndexPage.xaml"
<Button x:Name="One_green"
Content="1"
Background="Green"
Click="One_Click"
/>
<Button x:Name="One_red"
Content="1"
Background="Red"
Click="One_Click"
/>
Now I see red color button in my window as green button is hidden in the back.
Now, the following code is from another windows phone page "1.xaml"
<Button Content="GO" Click="Button_Click"/>
Now when the user clicks the "GO" Button I want the button to change to red to green in "IndexPage.xaml". So I tried a code something like this in "1.xaml.cs"
private void Button_Click(object sender, RoutedEventArgs e)
{
One_red.Visibility = Visibility.Collapsed;
One_green.Visibility = Visibility.Visible;
}
But I am not able to access the "One_red" or "One_green" button in the above code. Please shed me directions.
Also I want that code to execute only once. (i.e.) when the IndexPage.xaml loads again I want that button to be green always.
Thank you very much in advance.
Please tell me if some other details are required.
You could define a public or internal static variable inside the "Index.xaml" class specifying what button will show on load until otherwise specified. This variable could be accessed outside the class, and possibly even outside the project depending on the modifier chosen. The constructor of the "Index.xaml" class could have code to reset it to the default to ensure it only happens on the next creation of the page. If you aren't creating a new page everytime, you would have to put the default resetters in a method called when you want to bring it to foreground.
It seems to me that you are trying to learn, rather than having a SPEC to follow and implement.
Because of that, and because you are starting with C# in 2014 (almost 2015),
it will be quite beneficial for you to jump straight to data-binding declarative over imperative, going MVVM (MVVx) over MVC (MVx).
XAML was designed around this pattern. It's the natural way of doing things in XAML, a perfect fit and the perfect platform to learn the pattern.
It requires lots of learning, thinking, and re-learning, but it will open your eyes to modern programming techniques.
That said... there are too many ways of doing what you asked for, and while none are exactly wrong, there are 2 current trends in .Net/C#/MsTech which IMO are NOT a waste of your time:
Functional Reactive Programming and OOP/MVVx (the x is for whatever).
Examples are ReactiveUI, Reactive Extensions, PRISM, Caliburn.Micro and many more. They can be combined, the same way you can combine traditional event-driven/event callbacks with MVVM and/or Reactive Programming. However, I would advise against it.
I'll start with the most documented way.
Look at Data binding for Windows Phone 8. It was the first result when I googled "windows phone 8 xaml data binding," and deals with Colors and controls.
If you follow that example and add a resource to your application, you are done.
Of course, you can still use event => onClick + static class to hold the value in between View instances, but if I was right on the assumption that you are trying to learn, I wouldn't go that route.
Sorry if I drifted. :)
You may not be able to access the button click event because it is private, you may need to make it protected or public, the default access specifier would probably be ok as well.
public void Button_Click(object sender, RoutedEventArgs e)
or default would be:
void Button_Click(object sender, RoutedEventArgs e)

Using F1 Help (CHM format) With WPF

I've been working on a WPF application for a while, and the time has come to attach the CHM format help document to it.
But alas! HelpProvider, the standard way to show CHM files in Winforms, has magically vanished and has no counterpart in WPF. I've been trying to use WindowsFormsHost to spawn a new control so I can actually display the help, but essentially it just grabs control of the entire UI.
A little more detail: I've got a menu item that I want to, when clicked, open up the CHM file.
First I set up the WindowsFormsHost...
host = new System.Windows.Forms.Integration.WindowsFormsHost();
helpForm = new System.Windows.Forms.Control();
host.Child = helpForm;
host.Visibility = System.Windows.Visibility.Hidden;
this.grid1.Children.Add(host);
hp = new System.Windows.Forms.HelpProvider();
hp.HelpNamespace = "Somehelpfile.chm";
hp.SetHelpNavigator(helpForm, System.Windows.Forms.HelpNavigator.TableOfContents);
And then I say, voila, reveal yourself.
private void Help_Click(object sender, RoutedEventArgs e)
{
host.Visibility = Visibility.Visible;
helpForm.Show();
hp.SetShowHelp(helpForm, true);
}
I'm not really sure of where to proceed from here. When I show the helpForm, it obscures / overrides the existing UI and all I get is a gray, empty WPF window with no help file.
Any takers?
If you include System.Windows.Forms.dll you can also do:
System.Windows.Forms.Help.ShowHelp(null, #"help.chm");
Also, there's an article here about adding a context sensitive help system to WPF.
Call me crazy, but couldn't you just do:
System.Diagnostics.Process.Start(#"C:\path-to-chm-file.chm");
I am trying out Easy Help with WPF, which also addresses context sensitive help based on key words. So far it seems good. All I need to do is get cracking and write some decent help!
You can use http://www.pinvoke.net/default.aspx/hhctrl.HtmlHelp to open chm help at specified topic and to have more control of how chm window shown.
How about using the Help class instead of opening the file externally

Categories