Use real CultureInfo.CurrentCulture in WPF Binding, not CultureInfo from IetfLanguageTag
You can create a subclass of binding (e.g. CultureAwareBinding) which sets the ConverterCulture automatically to the current culture when created.
It's not a perfect solution, but it's probably the only one, since retroactively forcing Binding to respect the culture could break other code in WPF which depends on this behavior.
Let me know if you need more help!
Why WPF ignores my CultureInfo.CurrentCulture
Try setting
Thread.CurrentThread.CurrentUICulture
And maybe, you need to take a look to
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(
XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
WPF StringFormat on a Run component uses wrong culture
Also override the metadata for Run
elements:
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(Run), new FrameworkPropertyMetadata(
XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
Or set the Language
property explicitly:
<Run Text="{Binding Date, StringFormat=d}" Language="en-IN" FontWeight="Bold" />
A Run
is not a FrameworkElement
.
Which CultureInfo-property do i set to use it in all application threads
CultureInfo.DefaultThreadCurrentCulture
and CultureInfo.DefaultThreadCurrentUICulture
:
Set default thread culture for all thread?
The difference between Culture and UICulture is that the former affects formats (dates, currencies, etc.) while the latter affects resources:
What is the difference between Culture and UICulture?
Set culture with additional settings in WPF
There's couple options. Maybe the easiest one is to wrap the values you want to databind to screen and call ToString for them. For example, if you have:
public decimal Value
{
get { return this.value; }
set
{
if (value == this.value) return;
this.value = value;
OnPropertyChanged();
}
}
Wrap it inside your ViewModel like this:
public decimal Value
{
get { return this.value; }
set
{
if (value == this.value) return;
this.value = value;
OnPropertyChanged("ValueString");
}
}
public string ValueString
{
get { return this.value.ToString(CultureInfo.CurrentCulture); }
}
And bind your UI against this new property:
<TextBlock x:Name="Result" Text="{Binding ValueString}" Grid.Row="0"/>
This way you will automatically get the formatting based on your computer's culture settings:
Another alternative is to use the method presented in here: https://stackoverflow.com/a/19796279/66988
So you need a custom Binding class:
public class CultureAwareBinding : Binding
{
public CultureAwareBinding(string path)
: base(path)
{
ConverterCulture = CultureInfo.CurrentCulture;
}
}
And then you have to use that in your XAML:
<TextBlock x:Name="Result" Text="{wpfApplication9:CultureAwareBinding Value}" Grid.Row="0"/>
After which you should see the desired output:
WPF Overriding Current Culture is not reflecting in all controls or in UI elements
its been solved by using System.Reflection;
var culture = CultureInfo.CurrentCulture;
var language = XmlLanguage.GetLanguage(culture.IetfLanguageTag + "-current");
var type = typeof(XmlLanguage);
const BindingFlags kField = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly;
type.GetField("_equivalentCulture", kField).SetValue(language, culture);
type.GetField("_compatibleCulture", kField).SetValue(language, culture);
if (culture.IsNeutralCulture) culture = CultureInfo.CreateSpecificCulture(culture.Name);
type.GetField("_specificCulture", kField).SetValue(language, culture);
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(language));
How to change Application Culture in wpf?
try this
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
How to update property binding when changing the culture of the application at runtime in WPF .net core 5
The Answer
App.xaml.cs
public App()
{
CultureInfo CultureInformation = new CultureInfo("en-US");
CultureInformation.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
CultureInformation.DateTimeFormat.LongDatePattern = "ddd, dd/MM/yyyy";
CultureInfo.DefaultThreadCurrentCulture = CultureInformation;
CultureInfo.DefaultThreadCurrentUICulture = CultureInformation;
//
XmlLanguage language = XmlLanguage.GetLanguage(CultureInformation.IetfLanguageTag);
const BindingFlags kField = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly;
typeof(XmlLanguage).GetField("_equivalentCulture", kField).SetValue(language, CultureInformation);
typeof(XmlLanguage).GetField("_compatibleCulture", kField).SetValue(language, CultureInformation);
typeof(XmlLanguage).GetField("_specificCulture", kField).SetValue(language, CultureInformation);
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(language));
}
MainWindow.xaml.cs
private void UpdateLanguage(string Language)
{
LanguageComboBox.SelectedValue = Properties.Settings.Default.Language = Language;
Properties.Settings.Default.Save();
//
ResourceDictionary Dictionary = new();
Dictionary.Source = new Uri(@$"..\Languages\{Language}.xaml", UriKind.Relative);
Resources.MergedDictionaries.Clear();
Resources.MergedDictionaries.Add(Dictionary);
//
if (Language == "العربية")
{
CultureInfo CultureInformation = CultureInfo.CreateSpecificCulture("ar-EG");
CultureInformation.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
CultureInformation.DateTimeFormat.LongDatePattern = "ddd, dd/MM/yyyy";
Thread.CurrentThread.CurrentCulture = CultureInformation;
Thread.CurrentThread.CurrentUICulture = CultureInformation;
//
XmlLanguage language = XmlLanguage.GetLanguage(CultureInformation.IetfLanguageTag);
const BindingFlags kField = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly;
typeof(XmlLanguage).GetField("_equivalentCulture", kField).SetValue(language, CultureInformation);
typeof(XmlLanguage).GetField("_compatibleCulture", kField).SetValue(language, CultureInformation);
typeof(XmlLanguage).GetField("_specificCulture", kField).SetValue(language, CultureInformation);
this.Language = language;
}
else if (Language == "English")
{
CultureInfo CultureInformation = CultureInfo.CreateSpecificCulture("en-US");
CultureInformation.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
CultureInformation.DateTimeFormat.LongDatePattern = "ddd, dd/MM/yyyy";
Thread.CurrentThread.CurrentCulture = CultureInformation;
Thread.CurrentThread.CurrentUICulture = CultureInformation;
//
XmlLanguage language = XmlLanguage.GetLanguage(CultureInformation.IetfLanguageTag);
const BindingFlags kField = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly;
typeof(XmlLanguage).GetField("_equivalentCulture", kField).SetValue(language, CultureInformation);
typeof(XmlLanguage).GetField("_compatibleCulture", kField).SetValue(language, CultureInformation);
typeof(XmlLanguage).GetField("_specificCulture", kField).SetValue(language, CultureInformation);
this.Language = language;
}
}
There is NO ConverterCulture class
public class CultureAwareBinding : Binding
{
public CultureAwareBinding()
{
ConverterCulture = CultureInfo.CurrentCulture;
}
}
UserControl.xaml (Normal Binding)
<TextBlock Grid.Row="5" FontSize="14" FontFamily="{StaticResource Segoe Semibold}" Foreground="{DynamicResource BackgroundBrush}">
<TextBlock Text="{Binding Path=StartTime, StringFormat={}{0:hh:mm tt}}"/>
<TextBlock Text="" FontSize="12" FontFamily="{StaticResource Segoe Icons}"/>
<TextBlock Text="{Binding Path=EndTime, StringFormat={}{0:hh:mm tt}}"/>
</TextBlock>
Related Topics
Set System Time Zone from .Net
C# - Check If File Is Text Based
How to Handle Forms Authentication Timeout Exceptions in ASP.NET
Opening a "Known File Type" into Running Instance of Custom App - .Net
Internal .Net Framework Data Provider Error 1025
What Does "Displayclass" Name Mean When Calling Lambda
No Itemchecked Event in a Checkedlistbox
How to Implement the Sieve of Eratosthenes Using Multithreaded C#
Why Would Try/Finally Rather Than a "Using" Statement Help Avoid a Race Condition
.Net: Unable to Cast Object to Interface It Implements
Invalidprogramexception/Common Language Runtime Detected an Invalid Program
Combine Two Linq Lambda Expressions
How to Disable Aero Snap in an Application
Global Setting for Asnotracking()