Is it possible to set localized resources from Code Behind to AppResources.resx File? I tried googling it didn't help much either. When I try to Access AppResources.(Key), I am getting error since there is no setter for the properties :-(
A localized string is concidered as a constant and should not be modified after its definition. So instead of trying to set your localized String from codebehind or from AppResources.Designer.cs, you might want to add a new one using AppResources.resx.
Related
I have a C# .Net 4.5 WPF application.
The application have to be localizable. Which means I have to be able to change the labels/titles/button/text of everything visual in my application.
I have an existing model to take an id-String and return the text for the given language. Something like:
String localizedCancelText = Localize.Text("#Cancel"); //Cancel
String localizedMoneyLeftText = Localize.Text("#MoneyLeft",10); //$10 left
Where the Localize.Text(..) method is static.
This works all nicely.
The problem is with the labels/titles, thoses are set in WPF.
The idea is to have all labels(all visual) containing keywords insteed of english text. For example a WPF cancel button would be like:
<Button Content="#Cancel"/>
And then I have to take the "#Cancel" and lookup how cancel is written in the given language/location/department.
My question is:
How can I do this? I can set every label/button/text from codebehind, but that would be a ugly solution. I would much rather set it in WPF as shown above, and then "somehow" transelate the #Cancel using the Localize.Text(..) method to get the actual cancel text for the given language/location/department.
We use a software called Sisulizer that can parse the WPF and extract localizable strings. It can do that for all resources for that matter. We simply import all our resources into Sisulizer and the from there we export a csv file with required translations which we give our translators. Sisulizer builds satelite resource Dlls which we then use in our software.
it's better to use resource file .resx extension.you have to declare label and value in resx file.
My solution is based on this:
http://www.thomaslevesque.com/2009/07/28/wpf-a-markup-extension-that-can-update-its-target/
http://www.thomaslevesque.com/2009/08/23/wpf-markup-extensions-and-templates/
which allows me to use
<Button Content="{markUp:Localized Key=#BigButton}">
And still be able to change the language at runtime.
Here's the setup I'd like to have for my Windows Phone app, using c# in visual studio 2010:
**MainPage.xaml** contains elements that have an attached property, whose values will be modifiable/savable by the user.
**MainPage.xaml.cs**
first Namespace is PhoneApp ,inside it is a nested namespace called MyNamespace that declares the dependency property. it works(Thanks, Daniel)
**SettingsSample.xaml** that will allow users to change the values of the attached property in MainPage.xaml for any element and automatically save the change.
**AppSettings.cs** a class that exactly reproduces the first listing in this tutorial:
http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff769510%28v=vs.105%29.aspx
That page declares the same NameSpace as the MainPage.xaml.cs (PhoneApp), then a public class called AppSettings that is exactly like in the tutorial.
To join everything together, I did:
**MainPage.xaml**
xmlns:local="clr-namespace:PhoneApp.MyNamespace"
I needed this to use the attached property
<phone:PhoneApplicationPage.Resources>
<local:AppSettings x:Key="appSettings"></local:AppSettings>
</phone:PhoneApplicationPage.Resources>
Confusion begins. On the tutorial, they put this on the settings page, but I guess because their settings page is also the one including the elements with the properties that are bound to the saved settings. Mine are on the mainpage, so I put this here. To recap, My settings page will only use methods to change/save these values(and the methods are in AppSettings.cs). Also in the tutorial they add this:
xmlns:local="clr-namespace:SettingsSample"
to the Setting Page(where "SettingsSample" is the Namespace containing declaration/get-Set methods of savable settings) but, for the same reason, I tried to put it on the mainpage, but only one declaration of xmlns:local can be done. I tried several things to put them one after the other, but it doesn't work. This is the key to the two errors I'll list below.
Some elements of mainpage have this, for exemple:
local:MyClass.Son="{Binding Source={StaticResource appSettings}, Path=son1, Mode=TwoWay}" Style="{StaticResource pad}"
"Son" is the attached property
Ok, so I tried different different things but it never worked. The best I could get was in MainPage.xaml that it couldn't create an instance of AppSettings. Now it's different, I have the two errors.
-the type local:AppSettings was not found
-the tag AppSettings does not exist in xml namespace PhoneApp.MyNamespace.
I think this is because I didn't put the
xmlns:local="clr-namespace:PhoneApp"
But I already have
xmlns:local="clr-namespace:PhoneApp.MyNamespace"
and can't put both.(and to me, one is included in the other...) The reason I listed all the ins and out of the situation is because I kind of expect other troubles after I get through this.
I hope this message is clear enough for someone to help me. I spent so much time on it that I begin to loose my mind, so I hope there's no stupid mistake. Of course, I can add any information needed. Thank you for reading anyway!
These are XML namespace mappings. With the following:
xmlns:local="clr-namespace:PhoneApp"
The local part is the XML namespace, whilst PhoneApp is the namespace from your .NET code. With this definition in place you can then reference classes from this namespace in XML as follows:
<local:MyClassInPhoneAppNamespace/>
Because the local part is simply a name, you can change it to whatever you like:
xmlns:fish="clr-namespace:PhoneApp"
And use as follows:
<fish:MyClassInPhoneAppNamespace/>
This should mean that you no longer have collisions.
"local" in this case is simply a friendly name for the namespace you are referencing. It is completely interchangeable.
I was in need to import two local in same file as below
xmlns:local="clr-namespace:Generique.Views.Assets.Entries"
xmlns:local="clr-namespace:Generique.Views.Assets"
I just change the name and it works fine
xmlns:local="clr-namespace:Generique.Views.Assets.Entries"
xmlns:footer="clr-namespace:Generique.Views.Assets"
I have a resource file in a Class Library project. I'm using this resource file to hold various messages the user may end up seeing.
For example, the name of the resource is "InvalidEmailAddress" and the value in the en-US resource file is "Invalid Email Address".
When I call the ResourceManager's GetString(string) method I am doing this:
return resourceManager.GetString("InvalidEmailAddress");
However, this seems really bad to me. What if somebody changes the name of the resource? Now my statement will return a null value.
Is there a way around this issue?
UPDATE: Localization is an important factor here. The resource manager is used in order to ensure I can change the culture and get appropriate string values.
You can instead use an automatically generated class - the magic string constants will be removed from the code and replaced with strongly typed access methods. VS names this file ResourceName.Designer.cs and updates it every time resx is modified in VS.
Sample of a generated method:
internal static string String1 {
get {
return ResourceManager.GetString("String1", resourceCulture);
}
Note: while creating this file is the default behavior when you add a new resource in VS, you may have disabled it or you may have tried to use the generated resource outside the assembly. In that case, make sure to set the "Custom Tool" property or resx file to "PublicResXFileCodeGenerator" or "ResXFileCodeGenerator" (later if you use resources only inside a single assembly). (Thanks #dbaseman for comment).
When you create a Resource, it will be generated strongly typed in the Resources namespace.
You can access it by Resources.ClassName.InvalidEmailAddress where ClassName is the name of your Resource (resx) file.
In asp.net I use like this:
gridView_Desti.Columns["CODE_DEST"].Caption = (string) HttpContext.GetGlobalResourceObject("Client", "Code_Dest");
How can I do the same thing on WinForm ?
Client is the resource name file --> Client.resx
Code_Dest is string on Client.resx --> string Code_Dest, value Code Destinataire
You should have an auto-generated class called Resources in the Properties namespace of your project. Each resource is exposed as a property in that class.
You can do :
Client.ResourceManager.GetString("Code_Dest");
Depending on the culture, it will look for the string in Client.en-US.resx (if en-US is your current culture) and if it fail, in Client.resx.
You can also acces like this (Code_Dest must be in Client.resx) :
Client.Code_Dest;
Add new item -> Resources i.e 'Resources1.resx'
Put necessary Resources Name & value ie string resources -> 'YourResourcesName' value whatever.
Access its value with Resources1.YourResourcesName
Hope this help,
If you don't have the namespace in, then prepend with "Properties" C# as so:
Properties.Resources1.YourResourcesName
Makes your code so much cleaner using the resx file. As an example, I have a DataGridViewImageColumn and assigned an image to it (from VS Image Library - the image is a .png file):
colAddNewItem.Image = Properties.Resource1.Add_16x;
FYI, in VB.Net it's
Resources.Resources1.YourResourcesName
There are many other ways, but this is the simplest, cleanest & preferred method.
I've started using the WPF Localization Extension to localize my resources for WPF projects. I like the library because it can easily locate resource's out of the XAML-Code.
When I want to use the library to localize my resources in C# I have some problems. For a MessageBar (designed as UserControl in WPF) I want to set the displayed message in C# Code (ViewModel). The localized strings are stored in resource-files (the same which I used to localize strings in XAML).
Now my question, how can I localize my resources in C#-Code using the WPF Localization Extension? What is the best practice?
You can access your string values using this code.
public static string GetUIString(string key)
{
string uiString;
LocTextExtension locExtension = new LocTextExtension(key);
locExtension.ResolveLocalizedValue(out uiString);
return uiString;
}
Declare this method at a place where it is accessible to all the other classes. Then call it where ever you need the resource string and pass the resource key