就我而言:
我有一个TextBlock绑定到DateTime类型的属性。 我希望它显示为用户的区域设置。
<TextBlock Text="{Binding Date, StringFormat={}{0:d}}" />
我将语言属性设置为WPF XAML Bindings and CurrentCulture Display 表示:
this.Language = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag);
但是使用这行代码,它只会将文本显示为CultureInfo的默认格式 与CurrentCulture的IetfLanguageTag说,不是在系统区域设置中选择的有效值说:
(例如,使用“de-DE” dd.MM.yyyy 而不是选择 yyyy-MM-dd )
Binding有没有使用正确的格式而不在每个Binding上定义ConverterCulture?
代码
string.Format("{0:d}",Date);
使用正确的文化设置。
修改
另一种不能按预期工作的方式(比如this.Language = ......):
xmlns:glob="clr-namespace:System.Globalization;assembly=mscorlib"
和
<Binding Source="{x:Static glob:CultureInfo.CurrentCulture}"
Path="IetfLanguageTag"
ConverterCulture="{x:Static glob:CultureInfo.InvariantCulture}" />
答案 0 :(得分:26)
您可以创建一个绑定子类(例如CultureAwareBinding),它在创建时自动将ConverterCulture设置为当前文化。
这不是一个完美的解决方案,但它可能是唯一的解决方案,因为追溯强制Binding以尊重文化可能会破坏WPF中依赖于此行为的其他代码。
如果您需要更多帮助,请与我联系!
答案 1 :(得分:17)
这是来自aKzenT的答案的延伸。他们建议我们应该创建一个Binding类的子类,并将ConverterCulture设置为CurrentCulture。虽然答案非常简单,但我觉得有些人可能不太习惯实现它,所以我正在分享aKzenT答案的代码版本,并举例说明如何在XAML中使用它。
using System;
using System.Globalization;
using System.Windows.Data;
namespace MyWpfLibrary
{
public class CultureAwareBinding : Binding
{
public CultureAwareBinding()
{
ConverterCulture = CultureInfo.CurrentCulture;
}
}
}
如何在XAML中使用它的示例
1)您需要将名称空间导入XAML文件:
<Page
...
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:myWpfLib="clr-namespace:MyWpfLibrary;assembly=<assembly_name>"
...
>
2)CultureAwareBinding的实际使用
<Textblock Text="{myWpfLib:CultureAwareBinding Path=Salary, Source=Contact, StringFormat={}{0:C}}" />
答案 2 :(得分:5)
在初始化任何UI之前,请输入以下代码。这对我有用。
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement),
new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
(并删除所有显式文化参数)
答案 3 :(得分:2)
你的第二次尝试很接近,并引导我找到一个对我有用的解决方案。
设置ConverterCulture的问题在于它仅在您拥有Converter时使用。因此,只需创建一个简单的StringFormatConverter,将格式作为参数:
public sealed class StringFormatConverter : IValueConverter
{
private static readonly StringFormatConverter instance = new StringFormatConverter();
public static StringFormatConverter Instance
{
get
{
return instance;
}
}
private StringFormatConverter()
{
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Format(culture, (string)parameter, value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
然后你可以调整你的绑定(假设你已经将转换器的命名空间导入为“my”)
<TextBlock Text="{Binding Date, Converter={x:Static my:StringFormatConverter.Instance}, ConverterCulture={x:Static glob:CultureInfo.CurrentCulture}, ConverterParameter={}{0:d}}" />
答案 4 :(得分:2)
我根据自己的需要使用该代码。希望它可以填满你的:-)! 如果不能“TryParse”,也许你最好抛出异常。由你决定。
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;
}
}
用法:
<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>
答案 5 :(得分:2)
我提出了一个黑客/解决方法,可以避免更新所有绑定。将此代码添加到主窗口的构造函数中。
XmlLanguage language = XmlLanguage.GetLanguage("My-Language");
typeof(XmlLanguage).GetField("_compatibleCulture", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(language, CultureInfo.CurrentCulture);
this.Language = language;
由于它使用反射,因此不能保证它将来会起作用,但现在它确实如此(.NET 4.6)。
答案 6 :(得分:0)
我们可以使用IValueConverter创建DateTime转换器
[ValueConversion(typeof(DateTime), typeof(String))]
class DateTimeToLocalConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is DateTime)) return "Invalid DateTime";
DateTime DateTime = (DateTime)value;
return DateTime.ToLocalTime().ToShortDateString();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
如下所示在XAML中应用
Binding="{Binding Path=createdDateTime,Converter={StaticResource DateTimeConverter}}"
还要更改当前区域性以获取所需的格式,并且在应用程序启动时也需要应用相同的格式
/// <summary>
/// Set Culture
/// </summary>
private void SetCulture() {
var newCulture = new CultureInfo("en-IN");
newCulture.DateTimeFormat.ShortDatePattern = "dd-MMM-yyyy";
newCulture.DateTimeFormat.LongDatePattern = "dd-MMM-yyyy";
newCulture.DateTimeFormat.FullDateTimePattern = "dd-MMM-yyyy";
CultureInfo.DefaultThreadCurrentCulture = newCulture;
CultureInfo.DefaultThreadCurrentUICulture = newCulture;
Thread.CurrentThread.CurrentCulture = newCulture;
Thread.CurrentThread.CurrentUICulture = newCulture;
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(
System.Windows.Markup.XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
}
答案 7 :(得分:-1)
如何更改后面代码中的语言?
this.Language = XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentCulture.Name);
答案 8 :(得分:-1)
避免使用&#34; this.Language = XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentCulture.Name);&#34;实际上并不常见。我不知道法国的任何用户会将日期格式更改为美国或日本,只是因为至少没有用户知道这样的改变是可能的(并且不知道如何做)... 所以当然&#34;语言=&#34;并不完美,但在WPF和Silverlight实践的许多年里,我从来没有看到任何用户的这类问题...... 所以我仍然使用&#34; Langage =&#34;技巧,它很简单,涵盖了100%的实际需求。 当然,其他解决方案似乎更好,但没有必要(我看到一些实现与#34;语言=&#34;解决方案相比还远非完美。)