Use "Real" Cultureinfo.Currentculture in Wpf Binding, Not Cultureinfo from Ietflanguagetag

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:

Decimal formatting WPF binding culture

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:

Culture converter binding WPF

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



Leave a reply



Submit