The assorted options in the Windows 7 Region and Language dialog box correspond to the properties of the CurrentCulture object. However, WPF controls seem to use CurrentUICulture instead, which leads to a general rejection of user preferences.
On my workstation, for example, WPF controls seem to use CurrentUICulture, which is en-US, forcing them to display dates in the American format M / d / yyyy, rather than in the Australian format specified in the Region and Language dialog box .
Explicitly specifying an en-AU culture in data binding forces this control to use Australian default formats, but it continues to ignore user-specified formats. This is strange; entering the application, I confirmed that DateTimeFormatInfo.CurrentInfo == Thread.CurrentThread.CurrentCulture.DateTimeFormat (the same object) and DateTimeFormatInfo.CurrentInfo.ShortDatePattern == "yyyy-MM-dd" (the value that I set to determine or were raised by default). Everything was as expected, so at first glance, the big question is how to convince WPF controls and data bindings to use CurrentCulture rather than CurrentUICulture.
How should we receive WPF applications to comply with the region and language settings?
Based on Sphinxx's answer, I circumvented both Binding class constructors to provide more complete compatibility with standard markup.
using System.Globalization; using System.Windows.Data; namespace ScriptedRoutePlayback { public class Bind : Binding { public Bind() { ConverterCulture = CultureInfo.CurrentCulture; } public Bind(string path) : base(path) { ConverterCulture = CultureInfo.CurrentCulture; } } }
Further experimentation shows that you can use x: Static to reference System.Globalization.CultureInfo.CurrentCulture in the markup. This is a complete success at runtime, but a disaster at development time because the binding editor continues to delete it. The best solution is a helper class that traverses the DOM windows and captures the conversion culture of every Binding found.
using System; using System.Windows; using System.Windows.Data; using System.ComponentModel; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; namespace ScriptedRoutePlayback { public static class DependencyHelper { static Attribute[] __attrsForDP = new Attribute[] { new PropertyFilterAttribute(PropertyFilterOptions.SetValues | PropertyFilterOptions.UnsetValues | PropertyFilterOptions.Valid) }; public static IList<DependencyProperty> GetProperties(Object element, bool isAttached = false) { if (element == null) throw new ArgumentNullException("element"); List<DependencyProperty> properties = new List<DependencyProperty>(); foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(element, __attrsForDP)) { DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(pd); if (dpd != null && dpd.IsAttached == isAttached) { properties.Add(dpd.DependencyProperty); } } return properties; } public static IEnumerable<Binding> EnumerateBindings(DependencyObject dependencyObject) { if (dependencyObject == null) throw new ArgumentNullException("dependencyObject"); LocalValueEnumerator lve = dependencyObject.GetLocalValueEnumerator(); while (lve.MoveNext()) { LocalValueEntry entry = lve.Current; if (BindingOperations.IsDataBound(dependencyObject, entry.Property)) { Binding binding = (entry.Value as BindingExpression).ParentBinding; yield return binding; } } }
Peter Wone
source share