IT

wpf의 StringFormat 지역화 문제

lottoking 2020. 8. 4. 22:47
반응형

wpf의 StringFormat 지역화 문제


WPF 3.5SP1에서는 DataBindings의 마지막 기능인 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)));

에서 WPF에서 국제화 마법사 만들기


다음 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또는 한 것을 사용합니다 .

이 솔루션은 바인딩을 올바른 값으로 업데이트 하지만 너무 희귀하고 무해한 조치를위한 많은 코드처럼 좋습니다.


문화권 바로 가기를 최상위 태그에 삽입하십시오.

xml:lang="de-DE"

예 :

<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>

나는 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에서 사용할 때 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"

프로그램이 실행되는 동안 언어를 변경해야하는 경우 루트 요소의 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

런타임에 문화 정보를 변경하려면 동작을 사용할 수 있습니다 (아래 참조).

  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();
    }
}

XAML이 아닌 코드에서 작업하는 경우 다음과 같이 ConverterCulture를 설정할 수 있습니다.

binding.ConverterCulture = System.Globalization.CultureInfo.CurrentCulture;

기본 문화 정의를 사용하는 것과 사용자의 사용자 지정 문화 정의를 사용하는 것의 미묘한 차이를 지적한 @KZeise에 대한 찬사입니다.


texblock이 아닌 레이블 (Cultture 포함)을 사용하십시오.

참고 URL : https://stackoverflow.com/questions/520115/stringformat-localization-issues-in-wpf

반응형