I have following:
Code in Window's XAML
<Grid>
<Label Content="{x:Static properties:Resources.Caption}"/>
</Grid>
I have Resources.resx, Resources.cs.resx. In run time text in label is changed according to language on client's machine. I would like to see different localization in Visual Studio during design time.
During my investigation I even changed getter for Caption property in Resources.resx to following:
public static string Caption {
get {
return ResourceManager.GetString("Caption", new CultureInfo("cs-CZ"));
}
}
This of course hard-code localization in runtime, but still has no effect in design time. In design time I am still getting original Resources.resx value (I suppose it is result of fallback strategy). It seems that during design time localized resources cannot be accessed and therefore values from default one is used.
I would like to avoid using localization frameworks as WPFLocalizationExtension because I believe there should be some "native" way in Visual Studio.
Is there something I am missing that I am unable to get localized versions of strings in design time?
Related
Currently I having strange problem and trying the explain problem;
For design time, I am using following design instance on XAML side
d:DataContext="{d:DesignInstance Type={x:Type viewmodels:AddMeasurementEnterDataBaseStep},
IsDesignTimeCreatable=True}"
For localization of text using following binding extension
public class LocExtension : Binding
{
public LocExtension(string name)
: base("[" + name + "]")
{
this.Mode = BindingMode.OneWay;
this.Source = TranslationSource.Instance;
}
}
the usage of LocExtension: (Here, XYData key to resource, translated via resource manager)
<TextBlock Text="{ns:Loc XYData}" />
Everything works as expected during runtime, but at design time, it is displaying binding source as text.
DesingTime:
RunTime
Anyone facing similar issue?
UPDATE based on the question ask here
I have seen that, I might be activating 'Enable Project Code in XAML'. But it is somehow default deactivated:
I found the answer on MSDN
For projects that target ARM or X64 processors, Visual Studio cannot
run project code in the designer, so the Disable project code button
is disabled in the designer.
So, for X64 targeted projects, i have no chance :)
Thanks to James Montemagno for this plugin.[https://jamesmontemagno.github.io/SettingsPlugin ]
I have used it in my c# code easily: CrossSettings.Current.GetValueOrDefault("abc", "")
But I also want to use those settings in my XAML.
Before this plugin, I was using my own basic (inefficient) array setup and used: ...Text="{x:Static local:Settings.abc}"... Now I have completely converted over to this plugin. And it works well in c#, but am struggling to get it working in XAML.
I Tried {x:Static local:Helpers.Settings.GeneralSettings.abc}, and {x:Static helps:Settings.GeneralSettings.abc} (creating xmlns:help).
How can I use those settings in my XAML code?
The best way to do this is to set up a Property Accessor (get/set) - and bind the control to that method.
As a quick (one way) example..
Page Code behind
public int MyNumber
{
//This may be different, depending on what your Settings class has been named and where its reference has been stored - but it is the same plugin.
return App.Settings.GetValueOrDefault("myNumber",0);
}
XAML
<Label Text="{Binding MyNumber}"/>
You'll also want to make sure you've set the BindingContext. I find it easiest to do this after InitializeComponent(); in the page constructor, simply by using BindingContext = this;.
A more complex implementation (With two way data binding) can be found in the Settings Plugin Documentation.
I want to use localization in my project so I'm using ".resx" files.
I have two files "StringRes.resx" and "StringRes.fr.resx". As you can guess, I want that all the messages of my app change according to the CultureInfo of the user.
But when I do this :
public MainWindow()
{
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr");
InitializeComponent();
}
It doesn't change anything when I do :
Console.WriteLine(StringRes.FirstName);
Indeed, it's always the string in StringRes which is displayed and not the string from StringRes.fr
The both are in the same namespace.
Thank you for any help.
I have created my own test projected an I used "fr-FR" as a culture tag. The test project can be found on my skydrive.
Works perfect.
In short:
I set the culture in the Properties of the project to be en-US as that is what I would want my Resource.resx to be.
Then I created Resource.resx, Resource.fr-FR.resx and Resource.nl-NL.resx.
I filled them with the TestData string. And the created a window with 3 buttons with events hooked to them. Next to the buttons I created a textblock, the textblock is binded to a Text string field.
In the button events I change the culture and the Text field. And you can then see the change happen.
You first need to create your Resource.resx then in the same folder you need to create Resource.fr-FR.resx. The Resource.resx will get a codebehind file, all the cultured resource files should not. If your Resource.fr-FR.resx does have a culture file you did something wrong and it is best to delete that resources file and recreate it so it loses it's codebehind.
I have a custom control in WPF. I added two plain CLR property, that look like this:
private int _ChordFrom = 0;
public int ChordFrom
{
get { return _ChordFrom; }
set { _ChordFrom = value; }
}
private int _ChordTo = 0;
public int ChordTo
{
get { return _ChordTo; }
set { _ChordTo = value; }
}
I use plain CLR properties, because I don't want to bind these properties to any other dependency. I just want to set the values inside XAML, when the control is instantiated.
Inside XAML the properties are found by intellisense, but when building the project I get the error:
"The member "ChordFrom" is not recognized or is not accessible."
"The member "ChordTo" is not recognized or is not accessible."
The XAML code looks like this:
<TabItem Header="CHORDS I">
<Grid x:Name="_gridChords_1" Background="AliceBlue">
<mg:MidiChordGrid x:Name="gridMidiChordGrid_1" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ChordFrom="0" ChordTo="7"/>
</Grid>
</TabItem>
There are three things, I wonder about:
Why does Intellisense offers me the the properties inside XAML, if
they are not accessible?
If I close all XAML windows, rebuild the project, the errors
disappear.
Even if can build the project without any errors, the properties are
not set.
ANSWER | ANSWER | ANSWER | ANSWER | ANSWER | ANSWER | ANSWER
Thanks for all the answers, but the solution/error was inside my code. I forgot to update my grid after setting these two CLR properties. Sorry for this.
But here some facts you may want to know:
You can use and set plain CLR properties inside WPF XAML. I checked it out and the properties are set from XAML
The error "not recognized or is not accessible" seems to be a VS bug, because the project is buildable
If you close the XAML files inside VS there will be no build errors anymore
To me, using plain CLR properties is the best solution at this point, because the values I pass to the control are hardcoded for every instance of the control and they do not change at runtime. Of course I would want to use attached DPs, if the values changed at runtime, which they don't.
Thank for your quick answers, but it in the end it was a my fault.
I am just confirming that this appears to be a visual studio bug as mentioned in the question.
I added a couple properties to a control and spent an hour trying to figure out why it would not build. After reading the above post I simply closed the xaml file, clicked build and it built successfully.
Using VS 2013 community sp 4.
I have a WinForms app that I am currently implementing a translation engine in. What I have so far is a bunch of text documents that follow the syntax like:
messages.manualupdate="There is a manual update available for ProgName.\n\nDo you want to update to version {0}.{1}.{2}{3}?"
messages.errorcopy="Clicking OK will copy the error so you can paste it elsewhere!"
messages.error="Error"
messages.notsupported.title="Unsupported client"
messages.notsupported.message="This version is no long supported. Please wait for an update."
I have lots of these for different languages, for example:
messages.manualupdate="é disponibile un'aggiornamento manuale del programma ProgName.\n\nVuoi aggiornare alla versione {0}.{1}.{2}{3}?"
messages.errorcopy="Cliccando OK eseguirete una copia degli errori visualizzati"
messages.error="Error"
messages.notsupported.title="Client non supportato"
messages.notsupported.message="Questa versione non è utilizzabile al momento. attendi il prossimo aggiornamento!"
I then parse this into a DynamicObject which I can access like language.messages.notsupported.error. What I would like to know is if I can somehow link all the controls on the form to use variables from the dynamic object on creation. For instance I have a button on my form that I want to have the text "Error" in. Before the form shows, I set the language variable to the users chosen language, and then when the form shows it simply loads the text from language. Is there a way to do this in the designer rather than having to write a method that is called in the Forms constructor as it seems to me like a little bit of a waste to set all the button text to a value and then change them all when the form loads. I'm looking for a sort of binding, but to the controls Text parameter.
Anyone have any ideas?
MSDN has a walkthrough on string localization that might be of use to you link
Honestly, the approach you are trying to avoid looks best to me. I will suggest you to create a property for the control where you are trying to set the Text. In Set attribute, check for the language selected and get the appropriate text for you.
public string Error
{
set { _errorLabel.Text = value; }
}
private void SetText()
{
if(EnglishSelected)
Error = "English";
}
Regarding waste of time, well, I will just suggest not to set anything in designer and directly set the property in Load form. But I would like to add one more point here that any of the approach will not hit your application speed. First its about making your application expandable and maintainable and then about making it fast. Setting logical things in designer is always a bad practice. If your application is not tiny/small then I will suggest you to follow some design patterns like MVP and move all this logical things in Presenter. Not trying to preach but just suggesting.
And yes, in our company one of team is working in localization part of the application. Using resource may be a better way of doing this.
Hope it helps.