C# Localization Shortcuts - c#

I don´t know how i should explain what i want to do.
In my Project are basicly 3 Sub-Projects.
First Project: Holds all Properties and Localizations.
Second Project is an Console Project, using the Properties from the First Project and some Localized Strings.
Third Project is an Windows Forms Project, using all Properties and Localized Strings from the First Project.
The Localization is working without trouble, i can start both Projects and when i change the Culture, it changes the Strings.
But: I have to Write the whole Path to the String everywhere.
Example:
Label.Text = Config.Localization.MyString
With the Settings, i can use an "Shortcut" by setting it to an new variable:
private Settings settings = Config.Properties.Settings.Default;
But with the Localization i cant to that to shorten it up.
Try´d the following:
private Type locals = CodepackConfig.Localization;
Label.Text = locals.MyString
Does somebody have hint for me how i can set a Variable to "Config.Localization"? And yes, i just code C# for 1 Month now, looks like a stupidly easy error :)

Check out the using directive's documentation.
I assume you're interested in something like
using Localization = Config.Properties.Localization;
1: https://msdn.microsoft.com/en-us/library/sf0df423.aspx?f=255&MSPPError=-2147217396

Related

What is the best way to add i18n to an existing custom CMS system (build with C#)?

I am currently responsible for an existing CMS, built a few years ago with C# .Net and a few clients are requesting to have their website in Spanish. The websites are pre-populated with pages from a library and currently the application has no support for i18n. What is the quickest way to allow the client to have his website in Spanish? And what is the best way to allow any language?
I understand those are two different answers, but I want to plan for future and at the same time provide a quick solution to please the clients.
The simplest i18n solutions usually involve using a string dictionary for any text in the program.
Instead of doing things like:
TextBox t = new TextBox();
t.Text = "Hello, user!";
You'd do something like:
TextBox t = new TextBox();
t.Text = i18nStringDictionary["HelloUserMessage"]; //some people prefer an enum to
//bare strings in this case
Where i18nStringDictionary is a global or semi global dictionary. Then, on app start up you can initialize it with the proper values from a file as dictated by a config file. You'll have one file for each language. Illustrating the above example, in your english file, you'd have:
HelloUserMessage, "Hello, user!"
//More message pairs in english
and in your spanish file:
HelloUserMessage, "Hola, usario!"
//More message pairs in spanish.
Finally, you'd parse these pairs into a dictionary type.
Of course, this is only if you want to roll your own, but it demonstrates what most i18n libraries do under the covers. Otherwise, you can use the built in features of C# (https://msdn.microsoft.com/en-us/goglobal/bb688096.aspx), or find plenty of third party tools.
In any case, it probably won't be quick at all, since it involves replacing all string literals in the site/program with references to some dictionary or library. Once it is done, though, you will only need to do the translation and set config file variable and you'll be good to go.
Final edit:
Since you are talking about a website, you probably have views or templates with text in them as well. These would generally also need to be replaced with references to a string library.
Just search for ASP.NET globalization and localization.
Resource Files
You could add resource files (RESX) for all static text used in the ASP.NET controls.
Here is an MSDN article even covering Spanish.
Creating a new RESX file in Visual Studio will give you a table view. Let's say you add Text.resx to the project. This will be the default language.
| Name | Value |
| HelloWorld | Hello World ! |
| WelcomeMessage | Welcome ! |
You can now reference the Names in the code behind:
Label label = new Label();
label.Text = Text.WelcomeMessage;
Or you can set the binding in the designer
<asp:Label ID="Button1" runat="server"
Text="<%$ Resources:Text, WelcomeMessage %>" />
Switching language
Now to add another language simply create a new file named Text.language-country.resx. So in your case Text.es-ES.resx.
Each entry you add here will overwrite the default language when you switch to Spanish. If it is missing, then the default value will be shown.
| Name | Value |
| WelcomeMessage | ¡Bienvenidos! |
You can switch languages by changing the culture property of the current thread
Thread.CurrentThread.CurrentUICulture =
new CultureInfo("es-ES");
Otherwise the language can be set depending on browser settings.
More info here: https://msdn.microsoft.com/en-us/library/ff647353.aspx
Translation
RESX files are actually XML documents that can be embedded into an assembly are referenced as content files.
So you could send the default resource file to a translation agency for them to edit. Just remind them not to translate any entries in the Name column.

OmniSharp autocomplete for class names, not just methods/properties?

I'm a bit new to C# and trying to get Unity/Mono working with Vim. I get OmniSharp autocomplete for methods/properties, but would like the autocomplete to pop up for class names.
For example, if I am in the middle of typing the following, I do not get a suggested autocomplete:
new Vect
Now if I hit <C-x><C-o>, I do get the correct OmniSharp autocomplete suggestions for this class.
Is there any way for OmniSharp to suggest classes rather than only methods and properties?
Thanks.
I assume you mean you want the autocomplete to happen when you don't have the '.' in the front and assume you are using YouCompleteMe plugin
Add this line to your .vimrc:
let g:ycm_semantic_triggers = {'cs' : ['.','re![_a-zA-z0-9]']}

How can I convert a C# .NET application to support multiple languages?

I have a C# application that I need to convert to support English and Spanish, is there a semi easy way to add that in and be able to add other languages later on?
Yes! It's called resource (.resx) files. What you do is this:
Change the Localizable property of your localizable forms to true. This will make the designer fetch text and other properties from the .resx files instead of hard-coding them.
Create your program in one language, let's say English.
Next, change all your forms to another language like so:
Change the Language property of the form to the other language, let's say Spanish.
Change the text on all your controls. The designer will automatically generate a new .resx file for the language.
Swap back and forth as needed during development.
When publishing, go into your Assembly Settings and change the language. You can also change the language in code, I think.
And voilà! You're done!
You mark all your forms and controls as localizable. This will put all UI related text (labels etc.) in resource files. If you need to create strings in code then you use string resource files and look up the string by the resource key (e.g StringResource.Get("My_Message")). Then you can use a tool to translate all your resources. Typically you create a localized .dll for each language. We use Passolo for that but there are other tools around.
You can make a multilingual application in two ways:
By making the application Localizable, so when the user changes the culture of the device, the application will switch automatically to culture's UI if you added this language already to the supported languages in the application.
You can perform this by setting each form's Localizable property on the project to Localizable, and then changing the UI to the new culture.
By making a language option and a resource file (.resx) for each added language in your application, and depending on the selected language, you can load the images or the strings from selected language's resource file.
Without installing any 3rd party tool, APIs, or dll objects, I am able to utilize the App_LocalResources. Although I still use Google Translate for the words and sentences to be translated and copy and paste it to the file as you can see in one of the screenshots below (or you can have a person translator and type manually to add). In your Project folder (using MS Visual Studio as editor), add an App_LocalResources folder and create the English and other language (resx file). In my case, it's Spanish (es-ES) translation. See screenshot below.
Next, on your aspx, add the meta tags (meta:resourcekey) that will match in the App_LocalResources. One for English and another to the Spanish file. See screenshots below:
Spanish: (filename.aspx.es-ES.resx)
English: (filename.aspx.resx)
.
Then create a link on your masterpage file with a querystring that will switch the page translation and will be available on all pages:
<%--ENGLISH/SPANISH VERSION BUTTON--%>
<asp:HyperLink ID="eng_ver" runat="server" Text="English" Font-Underline="false"></asp:HyperLink> |
<asp:HyperLink ID="spa_ver" runat="server" Text="Español" Font-Underline="false"></asp:HyperLink>
<%--ENGLISH/SPANISH VERSION BUTTON--%>
.
On your masterpage code behind, create a dynamic link to the Hyperlink tags:
////LOCALIZATION
string thispage = Request.Url.AbsolutePath;
eng_ver.NavigateUrl = thispage;
spa_ver.NavigateUrl = thispage + "?ver=es-ES";
////LOCALIZATION
.
Now, on your page files' code behind, you can set a session variable to make all links or redirections to stick to the desired translation by always adding a querystring to urls.
On PageLoad:
///'LOCALIZATION
//dynamic querystring; add this to urls ---> ?" + Session["add2url"]
{
if (Session["version"] != null)
{
Session["add2url"] = "?ver=" + Session["version"]; //SPANISH version
}
else
{
Session["add2url"] = ""; // ENGLISH as default
}
}
///'LOCALIZATION
.
On Click Events sample:
protected void btnBack_Click(object sender, EventArgs e)
{
Session["FileName.aspx"] = null;
Response.Redirect("FileName.aspx" + Session["add2url"]);
}
I hope my descriptions were easy enough.

Localize additional strings in C# Control

I have a control which is localized. I'm using the VS Net designer and end up with MyControl.cs, MyControl.Designer.cs, MyControl.resx and some MyControl.xx.resx for the non-default languages.
Some of the strings that are displayed are dynamic and I need to call string.Format on them (eg I have "Hello, would you like to {0} today?", and I could format it using "read a book" or "watch TV"). How should I handle those dynamic strings?
For now I added the string to format in a label in the designer, but I don't know where to put the replacement strings. I could create an independent resx file just for them, but it feels like a mess just for a few strings. I could also have an independent resx file for all such strings throughout my application, but then it's like a potpourri and it sounds messy too.
The cleanest way would be to simply add those strings to the existing MyControl.resx and MyControl.xx.resx, but I dont know:
if it's safe (ie whether the VS Net designer will mess with them, just like I shouldn't manually modify the InitializeComponent method)
how to access those strings (in InitializeComponent I see how it's being used for a control resources.ApplyResources(this.myLabel, "myLabel"), but can I have a string which is not related to a control, and could I avoid using magic strings?)
I think you are looking for ResourceManager. The link also has an example for your case

put build date in about box

I have a C# WinForms app with an About box. I am putting the version number in the about box using:
FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location)
.FileVersion
This ends up giving me the Subversion revision number from which the executable was built.
I would also like to get the date of the build into the About box. I tried:
File.GetLastWriteTime(Assembly.GetEntryAssembly().Location)
But that gives me the write date of the executable, which only corresponds to the date when the app was installed (we are using ClickOnce) not built.
How can I get the build date?
If you use automatic versioning, you can convert the last two bits of the version number into a build date: MSDN
We're using this very similiar piece of code:
DateTime buildDate = new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime;
and I'm pretty sure it doesn't change when installing from ClickOnce.. If I'm wrong please correct me!
You could change your assembly versioning to encode the date, but that would probably mean losing your subversion revision information which is arguably more useful.
This should work: write the current date/time into a .cs file as a pre-build task like so:
[assembly: AssemblyCreated(CreatedDate = new DateTime(...))]
You could use a batch file, PowerShell script or executable for that.
Include the file in your project (build action: compile) and include the custom attribute:
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public sealed class AssemblyCreatedAttribute : Attribute
{
public DateTime CreatedDate { get; set; }
}
On application start you can use reflection to get the custom attribute from the assembly for display in the about page.
The only way i was able to do it in C/C++ was to actually have a post-build process do a search and replace of a special string allocated as a "static const" in the binary.
There might be an easier way in c# though.
I don't think a standard way of doing it exists, but you can roll something up yourself. Create a custom assembly-level attribute, give it a cool name like 'AssemblyDateAttribute'. Let it take a string that you can parse into a DateTime in the constructor that is accessible via a property.
As part of a build process, create a new file with only the attribute being applied to the assembly. (Make it look like AssemblyInfo.cs) and then include that in your build input.
Then in your about box, search your assembly for instances of this attribute and display the date value in your box.
In Visual Studio projects there is a file AssemblyInfo.cs, but you can use any other .cs file. Look at the attribute AssemblyVersion:
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0.*")]
Now you can calculate the build date by using the Version.Build property. The value that Version.Build returns is the number of days since: 2000/1/1
Assembly.GetExecutingAssembly().GetName().Version.ToString();
From my own C# code.

Categories