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.
Related
I have been working on this for days and I just don't get the concept of how Custom Actions work with Wix. Or at least I don't see how to do what I want.
I have several XML files that I want to read a value from and populate a property that gets displayed in a UI Dialog. Then when the install begins update that value in another XML file.
I need to be able to pass the filename including path of the local XML file and the node to search for and the key value pair to extract. I also need to pass what property needs to be updated.
I understand the CustomAction DLL concept. And that the session.CustomActionData["parametername"] syntax for passing in parameters. And the session["property"] = to set a property.
But I can't figure out the syntax of the wsx code to make it all happen. I read different examples doing it different ways?
I searched all the Google links out there an nothing seems to fit what I want to do?
You want this to be an immediate custom action not a deferred custom action so CustomActionData has no relevance to you.
What I would do is write a custom table like such:
Id [PK]
File (Formatted)
XPATH
Property
Here's an example:
mySearch
[SOMEPROPERTY]
/test[#'test'] (something like that, I hate xpath)
MYPROPERTY
You can use things like Property/FileSearch to have MSI's AppSearch resolve the location of a file and assign it to [SOMEPROPERTY]. Then you write a custom action scheduled after AppSearch to fetch this table's data, iterate it and fetch the attribute value (or element innertext) of each row and assign it to MYPROPERTY.
InstallShield gave this to me for free. I don't think WiX has a built in extension to do this. Maybe there is a community extension out there. It would probably take me an hour to write a prototype of this in C#/DTF.
I have written a dll in C# which has five .cs files. ControlsOnForm.cs has a public enum defined in it.
public enum FormControls {
Button,
Label,
DataGrid,
TextBox
}
Now, I'm using this dll in a Windows app which is shown in attached Image1 and when I click Generate button it generates the ControlsOnForm.cs C# file which is same as the enum in dll.
Now how do I refer/use this dynamically generated C# file with enum values in dll.
Or in another words the enum values in ControlsOnForm.cs of dll should get replaced with the newly generated C# file's enum values.
Thanks,
Although it is trivial to get your code to generate a cs file. I suspect what you then want to do is run the resulting code. That step is highly difficult and there are many things you need to understand in terms of the limitation.
However as another user has commented, it sounds like what you want to change is data, and not code.
You should understand the distinction between hardware, firmware, code, configuration and data. The lines are much more blurred than you might first think. But at the end of the day, each is a step in a continuum of changeability. For your purpose, code should be the thing that changes the least often. This in our tool chain it is the hardest to change. Remember at the end of the day everything is ones and zeros... and your data should also change how your program works.
Enums are a collection of named constants. In the same sense that you cannot change a constant, you cannot change an enum (at least without jumping through a ton of hoops).
What you really want to do here is use an external dataset, be it a datatable, an XML configuration file, etc.
On a side note, you would probably want to create an enum outside of a form, but in the same namespace. You can add a module to a project and drop all your enums in there.
From MSDN:
The enum keyword is used to declare an enumeration, a distinct type
that consists of a set of named constants called the enumerator
list.
Usually it is best to define an enum directly within a namespace so
that all classes in the namespace can access it with equal
convenience. However, an enum can also be nested within a class or
struct.
Reference: MSDN Enum Entry
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
I need to bind labels or items in a toolstrip to variables in Design Mode.
I don't use the buit-in resources not the settings, so the section Data is not useful. I am taking the values out from an XML that I map to a class.
I know there are many programs like:
http://www.jollans.com/tiki/tiki-index.php?page=MultilangVsNetQuickTourForms
but they work with compiled resx. I want to use not compiled XML.
I know that programatically i can do it, i create a method (for example, UpdateUI()), and there I assign the new values like this:
this.tsBtn.Text=Class.Texts.tsBtnText;
I would like something i could do from Design Mode or a more optimized way than the current one. Is there any Custom Control out there or Extension?
Aleksandar's response is one way to accomplish this, but in the long run it's going to be very time consuming and won't really provide much benefit. The bigger question that should be asked is why do you not want to use the tools and features built-in to .NET and Visual Studio or at least use a commercial third-party tool? It sounds like you are spending (have spent?) a lot of time to solve a problem that has already been solved.
Try with inheriting basic win controls and override OnPaint method. Example bellow is a button that has his text set on paint depending on value contained in his Tag property (let suppose that you will use Tag property to set the key that will be used to read matching resource). Then you can find some way to read all cache resource strings from xml files (e.g. fictional MyGlobalResources class.
public class LocalizedButton : Button
{
protected override void OnPaint(PaintEventArgs pevent)
{
base.OnPaint(pevent);
this.Text = MyGlobalResources.GetItem(this.Tag.ToString());
}
}
You can use satellite assemblies for localization and generate them using your XML file as a source for the translated entities.
more about satellites http://msdn.microsoft.com/en-us/library/21a15yht(VS.71).aspx
sure it's not from design mode, but there's no way to do it this way with your restrictions.