Use “real” CultureInfo.CurrentCulture in WPF Binding, not CultureInfo from IetfLanguageTag

前端 未结 9 775
余生分开走
余生分开走 2020-11-29 05:19

In my case:

I have a TextBlock Binding to a property of type DateTime. I want it to be displayed as the Regional settings of the User says.



        
相关标签:
9条回答
  • 2020-11-29 05:48

    I came up with a hack/workaround that avoids updating all your bindings. Add this code to the constructor of your main window.

    XmlLanguage language = XmlLanguage.GetLanguage("My-Language");
    typeof(XmlLanguage).GetField("_compatibleCulture", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(language, CultureInfo.CurrentCulture);
    this.Language = language;
    

    Since it's using reflection there is no guarantee that it will work in the future, but for now it does (.NET 4.6).

    0 讨论(0)
  • 2020-11-29 05:49

    This is an extension of answer from aKzenT. They proposed that we should create a subclass of Binding class and set the ConverterCulture to CurrentCulture. Even though the answer is very straight forward, I feel some people may not be very comfortable implementing it, so I am sharing the code version of aKzenT's answer with an example of how to use it in XAML.

    using System;
    using System.Globalization;
    using System.Windows.Data;
    
    namespace MyWpfLibrary
    {
        public class CultureAwareBinding : Binding
        {
            public CultureAwareBinding()
            {
                ConverterCulture = CultureInfo.CurrentCulture;
            }
        }
    }
    

    Example of how to use this in XAML

    1) You need to import your namespace into your XAML file:

    <Page
        ...
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:myWpfLib="clr-namespace:MyWpfLibrary;assembly=<assembly_name>"
        ...
    >
    

    2) Real world usage of the CultureAwareBinding

    <Textblock Text="{myWpfLib:CultureAwareBinding Path=Salary, Source=Contact, StringFormat={}{0:C}}" />
    
    0 讨论(0)
  • 2020-11-29 05:52

    I use that code with proper results to my needs. Hope it could fills your :-) ! Perhaps you are better throwing an exception if cannot "TryParse". Up to you.

    public sealed class CurrentCultureDoubleConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ((double)value).ToString((string)parameter ?? "0.######", CultureInfo.CurrentCulture);
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            double result;
            if (Double.TryParse(value as string, NumberStyles.Number, CultureInfo.CurrentCulture, out result))
            {
                return result;
            }
    
            throw new FormatException("Unable to convert value:" + value);
            // return value;
        }
    }
    

    Usage:

    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:simulatorUi="clr-namespace:SimulatorUi"
            xmlns:Converter="clr-namespace:HQ.Wpf.Util.Converter;assembly=WpfUtil" x:Class="SimulatorUi.DlgTest"
            Title="DlgTest" Height="300" Width="300">
        <Window.DataContext>
            <simulatorUi:DlgTestModel/>
        </Window.DataContext>
    
        <Window.Resources>
            <Converter:CurrentCultureDoubleConverter x:Key="CurrentCultureDoubleConverter"/>
        </Window.Resources>
    
        <Grid>
            <TextBox Text="{Binding DoubleVal, Converter={StaticResource CurrentCultureDoubleConverter}}"/>
        </Grid>
    </Window>
    
    0 讨论(0)
提交回复
热议问题