WPF tripwires, beware of uncommon culture infos
I got a few bug reports about NH Prof giving an error that looks somewhat like this one:
System.Windows.Markup.XamlParseException: Cannot convert string '0.5,1' in attribute 'EndPoint' to object of type 'System.Windows.Point'. Input string was not in a correct format.
It took a while to figure out exactly what is going on, but I finally was able to track it down to this hotfix (note that this hotfix only take cares of list separator, while the problem exists for the decimal separator as well. Since I can’t really install the hotfix for all the users of NH Prof, I was left with having to work around that.
I whimpered a bit when I wrote this, but it works:
private static void EnsureThatTheCultureInfoIsValidForXamlParsing() { var numberFormat = CultureInfo.CurrentCulture.NumberFormat; if (numberFormat.NumberDecimalSeparator == "." && numberFormat.NumberGroupSeparator == ",") return; Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US"); Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US"); }
I wonder when I’ll get the bug report about NH Prof not respecting the user’s UI culture…
Comments
So what you're telling me is that WPF can't parse floating point numbers if decimal separator is something else than a dot? You can't be serious!
So funny, just yesterday I've found that XML Schema Validator in .NET uses hard-coded InvariantCulture number format which means it requires dot to be decimal separator when validating values of double type :\
Hello,
There might be a CultureInfo override where you can pass in CultureInfo.InvariantCulture, which is much cleaner.
Thanks
-Blake Niemyjski
Ivan, isn't that because XML Schema requires dot to be decimal separator?
Perhaps this is the case with XAML too?
Does it work just to set CurrentCulture? It's been a while since I had to know the difference, but it seems like the parser would just use one or the other, and it would make sense if it used CurrentCulture and let your app use CurrentUICulture...
InvariantCulture would probably be better, and is really what the parser should be using, I would think...
mmh. French is certainly less common than en-us but calling it uncommon seems like a stretch. It would be interesting to have more context around that as the sledgehammer solution of reverting to en-us seems a little heavy handed without it. It would also help understanding if that's a bug in framework code or in NH Prof... Or at all (the document may be plain invalid).
Since the hotfix specifically states that it only applies to US English installations of Windows, shouldn't your function start with:
if (CultureInfo.CurrentCulture.Name != "en-US")
as the idea isn't to change the culture, but only to get rid of any customizations the user might have done in their control panel settings. I've had to add those 2 culture lines to unit test setup methods as time strings have failed to match because I have my system set to display in 24 hour time instead of 12. This situation looks very similar.
So, WPF does seem to have a bug in its internals where it doesn't use the invariant culture to parse XAML? Ouch.
As far as I am aware WPF parses floating point values using invariant culture. Otherwise the use of a custom converter class would be a pretty clean option to perform conversion.
Bertrand,
You are absolutely correct that this isn't an ideal solution, not by a long shot.
The bug seems to be in the framework, as specified in the hotfix.
I changed the code so it would only revert the culture when the root culture in en-US.
John,
Thank you, I added the same condition
Ah, so there is a hotfix then. That is encouraging as it means it will probably be fixed for good in 4.0. Does it make sense for me to follow-up on the part of the problem that is not addressed by the hotfix? We can follow-up offline if you want.
@ Rik Hemsley
Yeah, you're right, W3C requires period to be decimal indicator, see http://www.w3.org/TR/xmlschema-2/#decimal
I wonder why Xaml parser is not using InvariantCulture for things that aren't supposed to be localized.
Bertrand
I would like to know if this really does affect only en-US, so yes, thank you
I've asked. I'll report here when I hear back from them.
thanks
Ayende-
Bertrand let us know about this issue you have found. Thanks Bertrand.
We did this QFE this year, and we intended to fix the entire issue...but we'll dig into your example, and go see what we find.
.NET 4 Beta2 will contain our .NET 4 version of this QFE.
Sounds, from your error string, that it is complaining about a LinearGradientBrush.EndPoint...which is of type Point, which means PointConverter is the one not working well.
We'll get back to you soon on that.
XAML parsing, since v3 uses en-us, and not invariant. Unfortunately, en-us can be customized by a user who changes settings in the control panel. Our QFE is to continue to use en-us (for best compat), but to make it so that user overrides will no longer apply.
It is possible that one of our type converters is still using the normal en-us, in which this problem would still show up.
Thanks for raising this issue...we realize it is a critical issue, which is why we worked on the earlier fix.
Thanks, Rob
Rob Relyea | WPF & Xaml Language Team
robrelyea.com | /blog | /wpf | /xaml
Comment preview