programing

wpf의 문자열 형식 현지화 문제

yellowcard 2023. 5. 20. 10:38
반응형

wpf의 문자열 형식 현지화 문제

WPF 3.5에서SP1 i는 데이터 바인딩의 마지막 기능 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또는 당신이 제공한 모든 것.

이 솔루션은 바인딩을 올바른 값으로 즉시 업데이트하지만 매우 드물고 유해하지 않은 것에 대한 많은 코드처럼 보입니다.

저는 로더론의 대답이 대부분의 경우에 효과가 있다는 것을 덧붙이고 싶었습니다.App.xaml.cs 에 다음 코드 줄을 입력하면 텍스트 블록의 날짜가 올바른 문화로 포맷됩니다.

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)

...그러나 텍스트 블록에서 실행을 사용하는 경우 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)

이 추가 답변이 누군가에게 도움이 되길 바랍니다.

최상위 태그에 문화 바로 가기를 삽입하기만 하면 됩니다.

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>

이미 언급했듯이 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"

프로그램이 실행되는 동안 언어를 변경해야 하는 경우 루트 요소의 언어 속성만 변경하면 됩니다(즉각 효과가 있는지 아니면 하위 요소를 다시 만들어야 하는지는 확실하지 않습니다. 이 경우 최소한 작동합니다.)

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이 아닌 코드로 작업하는 경우 Converter Culture를 다음과 같이 설정할 수 있습니다.

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

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

언급URL : https://stackoverflow.com/questions/520115/stringformat-localization-issues-in-wpf

반응형