View previous topic :: View next topic |
Author |
Message |
MaKo
Joined: 20 May 2010 Posts: 5
|
Posted: Fri May 21, 2010 8:12 am Post subject: Funny error thanslating RoutedUICommand.Text |
|
|
Hi Infralution
I'm evaluating Globalizer and the ResxExtension and I like it very much so far.
However, I've got a funny problem translating the RoutedUICommand text.
In xaml, I bind the Button.Context to the corresponding command text, like this:
Code: |
Button
Command="{x:Static l:MainWindow.TestCmd}"
Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}" |
I create the RoutedUICommand static object in my code like this:
Code: |
static public RoutedUICommand TestCmd {get; private set;}
static MainWindow()
{
TestCmd = new RoutedUICommand("Here we go", "testCmd", typeof(MainWindow));
}
|
So, I have to translate the command text in my code. I use the following static method to do that:
Code: |
private static ResourceManager _srm = null;
private static string Tr(string key)
{
if(_srm == null)
{
_srm = new ResourceManager(typeof(MainWindow).FullName, Assembly.GetExecutingAssembly());
}
string returnValue = key;
try
{
if((returnValue = _srm.GetString(key)) == null)
returnValue = key;
}
catch(MissingManifestResourceException ex)
{
System.Diagnostics.Debug.WriteLine("Tr: " + ex.Message);
}
return returnValue;
}
|
Then, in event handler, I translate the command text using command name as the key:
Code: |
void CultureManager_UICultureChanged(object sender, EventArgs e)
{
UpdateLanguageMenus();
// Translate command text
string text = Tr(TestCmd.Name);
TestCmd.Text = text;
// The string is OK in debug window, but WRONG in the button Content!
System.Diagnostics.Debug.WriteLine(text);
}
|
The problem is that the button.Content shows the SECOND LAST language, e. g. when I change the languages en -> de -> fr, -> en I get (nothing) ->en ->de ->fr!
In the command executed method, I simply show a MessageBox with the translated text. Again, the text in the MessageBox is OK!
Code: |
private void CmdExecuted(object sender, ExecutedRoutedEventArgs e)
{
// Show translated text
// The string is OK in MessageBox, but WRONG in the button Content!
MessageBox.Show(Tr(TestCmd.Name), this.Title);
}
|
What I'm doing wrong?
I can e-mail you a small but complete test solution, if you wish.
Thanks for any help. |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Fri May 21, 2010 10:55 pm Post subject: |
|
|
If you can email a zipped copy of your test solution to support@infralution.com that would be very helpful. _________________ Infralution Support |
|
Back to top |
|
|
MaKo
Joined: 20 May 2010 Posts: 5
|
Posted: Sun May 23, 2010 11:53 am Post subject: Solution sent |
|
|
I've emailed the test solution to you. Thanks! |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Mon May 24, 2010 12:12 am Post subject: |
|
|
Thanks for the sample project. I can't see why you are getting this behaviour - however I think it is related to the way you are binding the button text to the TestCmd.Text. If you set the button text directly in UICultureChanged handler like:
Code: | string text = Tr(TestCmd.Name);
TestCmd.Text = text;
this._button.Content = TestCmd.Text; |
This works fine. This indicates that the issue is in the way you have bound the _button.Content to TestCmd.Text. I think that the most likely explanation is that the Command.Text property does not support change notification and so the button Content is not automatically be updated and only changes next time the page is rendered. _________________ Infralution Support |
|
Back to top |
|
|
MaKo
Joined: 20 May 2010 Posts: 5
|
Posted: Mon May 24, 2010 4:57 pm Post subject: |
|
|
Thanks for your qiuck answer. What a pity! One of the advantages of using RoutedCommand is that one can bind it to more than one control (MenuItem in main menu and popup menu, Button, Gesture etc) and still handle the bound control's state (enabled, executed and, in case of RoutedUICommand, also the content) in one place, the system does the rest automatically. That's why I bound the button's content to the command text. In my real world project I'm doing that for menu items and other controls too - it's enough to change the command text, and voila - the content of all controls bound to that command changes automatically.
Anyway, I will poke about that further. I'm surely not happy to have to give away the abovementioned advantages. If somebody here could help me, I'd appreciate it very much indeed. |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Mon May 24, 2010 10:21 pm Post subject: |
|
|
I've just run another little test which verifies the issue is nothing to do with translation. I change the TestCmd.Text directly in the menu click event handlers eg
Code: | private void _englishMenuItem_Click(object sender, RoutedEventArgs e)
{
TestCmd.Text = "English";
// CultureManager.UICulture = new CultureInfo("en");
} |
The text of the button then doesn't change at all. _________________ Infralution Support |
|
Back to top |
|
|
MaKo
Joined: 20 May 2010 Posts: 5
|
Posted: Mon May 24, 2010 10:49 pm Post subject: |
|
|
Thanks you are really looking at that. As I'm in my holiday for a week or so, we could probably experience a short break in our conversation. However, I'm chasing that problem really hard on my own. I'm excited about chasing it and make it work with your system. After all, I'd like to see it to do what it's supposed to do by both of us... |
|
Back to top |
|
|
MaKo
Joined: 20 May 2010 Posts: 5
|
Posted: Thu Jun 03, 2010 11:12 am Post subject: |
|
|
Hi Infralution
I've solved the problem for me in a simple way.
You were right saying Quote: | the Command.Text property does not support change notification and so the button Content is not automatically be updated | So, my solution is to create a simple class derived from RoutedCommand with a property DisplayText which does support change notification, like this:
Code: | public class RoutedLocalizableCommand: RoutedCommand, INotifyPropertyChanged
{
public RoutedLocalizableCommand(string text, string name, Type ownerType): base(name, ownerType)
{
DisplayText = text;
}
public string DisplayText
{
get {return _displayText;}
set
{
if(_displayText != value)
{
_displayText = value;
if(PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("DisplayText"));
}
}
}
private string _displayText = string.Empty;
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
} |
Now I can bind the Button.Content or MenuItem.Header to the Command.DisplayText and everything's working just fine!
Thanks for your clever suggestion. |
|
Back to top |
|
|
Infralution
Joined: 28 Feb 2005 Posts: 5027
|
Posted: Thu Jun 03, 2010 10:30 pm Post subject: |
|
|
Great. Thanks for sharing your solution. _________________ Infralution Support |
|
Back to top |
|
|
|