在 WPF 3.5SP1 中,我使用了数据绑定中的最新功能 StringFormat:
<TextBlock Text="{Binding Path=Model.SelectedNoteBook.OriginalDate, StringFormat='f'}"
FontSize="20" TextTrimming="CharacterEllipsis" />
我面临的问题是,日期始终以英文格式显示...尽管我的系统是法语?如何强制日期遵循系统日期?
在 WPF 3.5SP1 中,我使用了数据绑定中的最新功能 StringFormat:
<TextBlock Text="{Binding Path=Model.SelectedNoteBook.OriginalDate, StringFormat='f'}"
FontSize="20" TextTrimming="CharacterEllipsis" />
我面临的问题是,日期始终以英文格式显示...尽管我的系统是法语?如何强制日期遵循系统日期?
// Ensure the current culture passed into bindings is the OS culture.
// By default, WPF uses en-US as the culture, regardless of the system settings.
FrameworkElement.LanguageProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(
XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
定义以下XML命名空间:
xmlns:gl="clr-namespace:System.Globalization;assembly=mscorlib"
现在看看这个奇妙的修复:
<TextBlock Text="{Binding Path=Model.SelectedNoteBook.OriginalDate, StringFormat='f', ConverterCulture={x:Static gl:CultureInfo.CurrentCulture}" FontSize="20"TextTrimming="CharacterEllipsis" />
我很清楚这不是全局性的解决方案,你需要在每个绑定上使用它,但这难道不是良好的XAML实践吗?据我所知,下一次绑定更新时将会使用正确的 CultureInfo.CurrentCulture
或您提供的任何其他值。
这个解决方案可以立即更新您的绑定并提供正确的值,但对于如此罕见且无害的事情来说,代码量似乎有点多。
我只是想要补充一点,loraderon的答案在大多数情况下都很有效。当我将以下代码行放入我的App.xaml.cs中时,我的TextBlocks中的日期会以正确的文化格式进行格式化。
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(System.Windows.Markup.XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
我说“大多数情况”。例如,这将立即生效:
<TextBlock Text="{Binding Path=Date, StringFormat={}{0:d MMMM yyyy}}" />
--> "16 mei 2013" (this is in Dutch)
…但当在TextBlock中使用Run时,DateTime会按默认区域设置格式化。
<TextBlock>
<Run Text="Datum: " />
<Run Text="{Binding Path=Date, StringFormat={}{0:d MMMM yyyy}, Mode=OneWay}" />
</TextBlock>
--> "Datum: 16 may 2013" (this is in English, notice the
name of the month "may" vs. "mei")
为使其工作,我需要Gusdor的答案,即在绑定中添加ConverterCulture={x:Static gl:CultureInfo.CurrentCulture}。
<TextBlock>
<Run Text="Datum: " />
<Run Text="{Binding Path=Date, StringFormat={}{0:d MMMM yyyy}, ConverterCulture={x:Static gl:CultureInfo.CurrentCulture}, Mode=OneWay}" />
</TextBlock>
--> "Datum: 16 mei 2013" (=Dutch)
我希望这个补充回答能对某个人有所帮助。
如前所述,XAML默认使用不变文化(en-US),您可以使用
FrameworkElement.LanguageProperty.OverrideMetadata(
typeof(FrameworkElement),
new FrameworkPropertyMetadata(
XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
将文化设置为当前文化语言的默认文化。但是注释是错误的;因为它不使用当前文化,所以您将看不到用户可能进行的任何自定义,它始终是该语言的默认值。
要实际使用具有自定义的当前文化,您需要将ConverterCulture
与StringFormat
一起设置,例如
Text="{Binding Day, StringFormat='d', ConverterCulture={x:Static gl:CultureInfo.CurrentCulture}}"
在您的根元素中将gl
定义为全局命名空间
xmlns:gl="clr-namespace:System.Globalization;assembly=mscorlib"
binding.ConverterCulture = System.Globalization.CultureInfo.CurrentCulture;
- Metalogic只需将 culture 快捷方式插入到顶级标记即可:
xml:lang="de-DE"
e.g.:<Window x:Class="MyApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xml:lang="de-DE"
Title="MyApp" Height="309" Width="497" Loaded="Window_Loaded">....</Window>
如果您需要在程序运行时更改语言,只需更改根元素上的Language属性(我不确定这是否会立即生效或者子元素是否需要重新创建,在我的情况下至少可以使用此方法)
element.Language = System.Windows.Markup.XmlLanguage.GetLanguage(culture.IetfLanguageTag);
<Run />
这样的元素,代码如下:Private Shared Sub SetXamlBindingLanguage()
'' For correct regional settings in WPF (e.g. system decimal / dot or comma)
Dim lang = System.Windows.Markup.XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)
FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(TextElement), New FrameworkPropertyMetadata(lang))
FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(DefinitionBase), New FrameworkPropertyMetadata(lang))
FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(FixedDocument), New FrameworkPropertyMetadata(lang))
FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(FixedDocumentSequence), New FrameworkPropertyMetadata(lang))
FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(FlowDocument), New FrameworkPropertyMetadata(lang))
FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(TableColumn), New FrameworkPropertyMetadata(lang))
FrameworkElement.LanguageProperty.OverrideMetadata(GetType(FrameworkElement), New FrameworkPropertyMetadata(lang))
End Sub
如果你正在编写代码而不是 XAML,你可以按如下方式设置 ConverterCulture:
binding.ConverterCulture = System.Globalization.CultureInfo.CurrentCulture;
public class CultureBehavior<TControl> : Behavior<TControl>
where TControl : FrameworkElement
{
private readonly IEventAggregator _eventAggregator;
private readonly Action<CultureInfo> _handler;
public CultureBehavior()
{
_handler = (ci) => this.AssociatedObject.Language = XmlLanguage.GetLanguage(ci.IetfLanguageTag);
_eventAggregator = IoC.Container.Resolve<IEventAggregator>();
}
protected override void OnAttached()
{
base.OnAttached();
_eventAggregator
.GetEvent<LanguageChangedEvent>()
.Subscribe(_handler);
_handler.Invoke(CultureInfo.CurrentCulture);
}
protected override void OnDetaching()
{
_eventAggregator
.GetEvent<LanguageChangedEvent>()
.Unsubscribe(_handler);
base.OnDetaching();
}
}