전체 응용 프로그램의 문화를 설정하는 방법이 있습니까? 모든 현재 스레드와 새 스레드?
우리는 데이터베이스에 저장된 문화의 이름을 가지고 있으며 응용 프로그램이 시작될 때
CultureInfo ci = new CultureInfo(theCultureString);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
그러나 물론 새로운 스레드에서 무언가를 원할 때 “손실”됩니다. 것을 설정하는 방법이 CurrentCulture
와 CurrentUICulture
전체 응용 프로그램은? 그래서 새로운 스레드도 그 문화를 얻습니까? 아니면 새 스레드를 만들 때마다 연결될 수있는 이벤트가 발생합니까?
답변
.NET 4.5에서는이 CultureInfo.DefaultThreadCurrentCulture
속성을 사용하여 AppDomain의 문화권을 변경할 수 있습니다 .
4.5 이전 버전의 경우 리플렉션을 사용하여 AppDomain의 문화를 조작해야합니다. 스레드가 해당 속성을 자체적으로 설정하지 않은 경우 반환되는 내용을 제어 하는 개인 정적 필드 CultureInfo
( m_userDefaultCulture
.NET 2.0 mscorlib, s_userDefaultCulture
.NET 4.0 mscorlib)가 CurrentCulture
있습니다.
이것은 기본 스레드 로케일을 변경하지 않으며 문화를 이런 식으로 변경하는 코드를 제공하는 것은 좋지 않습니다. 그래도 테스트에 유용 할 수 있습니다.
답변
이것은 많은 질문을받습니다. 기본적으로 .NET 4.0에는 없습니다. 각각의 새 스레드 (또는 ThreadPool
기능) 가 시작될 때 수동으로 수행해야합니다 . 문화권 이름 (또는 문화권 객체)을 정적 필드에 저장하여 DB를 칠 필요가 없도록 할 수는 있지만 그게 전부입니다.
답변
리소스를 사용하는 경우 다음을 통해 수동으로 리소스를 강제 실행할 수 있습니다.
Resource1.Culture = new System.Globalization.CultureInfo("fr");
자원 관리자에는 다음과 같은 자동 생성 코드가 있습니다.
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
이제이 리소스 내에서 개별 문자열을 참조 할 때마다 지정된 resourceCulture를 사용하여 문화권 (스레드 또는 프로세스)을 재정의합니다.
“fr”, “de”등의 언어를 지정하거나 en-US의 경우 0x0409, it-IT의 경우 0x0410과 같이 언어 코드를 입력 할 수 있습니다. 언어 코드의 전체 목록은 언어 식별자 및 로캘을 참조하십시오.
답변
.net 4.5 이상의 경우
var culture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
답변
실제로 기본 스레드 문화권 및 UI 문화권을 설정할 수 있지만 Framework 4.5 이상에서만 가능합니다.
이 정적 생성자를 넣었습니다.
static MainWindow()
{
CultureInfo culture = CultureInfo
.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
var dtf = culture.DateTimeFormat;
dtf.ShortTimePattern = (string)Microsoft.Win32.Registry.GetValue(
"HKEY_CURRENT_USER\\Control Panel\\International", "sShortTime", "hh:mm tt");
CultureInfo.DefaultThreadCurrentUICulture = culture;
}
ValueConverter의 Convert 메서드에 중단 점을 넣어 다른 쪽 끝에 도착한 것을 확인하십시오. CultureInfo.CurrentUICulture는 en-US로 중단되었으며 대신 ShortTimePattern의 지역 설정을 존중하기 위해 작은 핵으로 완성되었습니다.
Hurrah, 세상은 모두 잘 지내고 있습니다! 아님 Convert 메서드에 전달 된 culture 매개 변수는 여전히 en-US입니다. 음, WTF ?! 그러나 시작입니다. 적어도 이런 식으로
- 앱이로드 될 때 UI 문화를 한 번 수정할 수 있습니다
- 그것은 항상 접근 할 수 있습니다
CultureInfo.CurrentUICulture
string.Format("{0}", DateTime.Now)
맞춤 지역 설정을 사용합니다
버전 4.5의 프레임 워크를 사용할 수 없다면 CurrentUICulture를 CultureInfo의 정적 속성으로 설정하지 말고 자신의 클래스 중 하나의 정적 속성으로 설정하십시오. 이것은 문자열의 기본 동작을 수정하지 않습니다. 바인딩에서 바인딩 또는 StringFormat이 제대로 작동하도록 한 다음 앱의 논리 트리를 따라 이동하여 앱의 모든 바인딩을 다시 만들고 변환기 문화를 설정하십시오.
답변
ASP.NET5, 즉 ASPNETCORE의 경우 다음을 수행 할 수 있습니다 configure
.
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture(new CultureInfo("en-gb")),
SupportedCultures = new List<CultureInfo>
{
new CultureInfo("en-gb")
},
SupportedUICultures = new List<CultureInfo>
{
new CultureInfo("en-gb")
}
});
자세한 정보를 제공 하는 일련의 블로그 게시물 이 있습니다.
답변
이 답변은 @rastating의 훌륭한 답변을 약간 확장 한 것입니다. 걱정없이 모든 버전의 .NET에 다음 코드를 사용할 수 있습니다.
public static void SetDefaultCulture(CultureInfo culture)
{
Type type = typeof (CultureInfo);
try
{
// Class "ReflectionContext" exists from .NET 4.5 onwards.
if (Type.GetType("System.Reflection.ReflectionContext", false) != null)
{
type.GetProperty("DefaultThreadCurrentCulture")
.SetValue(System.Threading.Thread.CurrentThread.CurrentCulture,
culture, null);
type.GetProperty("DefaultThreadCurrentUICulture")
.SetValue(System.Threading.Thread.CurrentThread.CurrentCulture,
culture, null);
}
else //.NET 4 and lower
{
type.InvokeMember("s_userDefaultCulture",
BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
null,
culture,
new object[] {culture});
type.InvokeMember("s_userDefaultUICulture",
BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
null,
culture,
new object[] {culture});
type.InvokeMember("m_userDefaultCulture",
BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
null,
culture,
new object[] {culture});
type.InvokeMember("m_userDefaultUICulture",
BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Static,
null,
culture,
new object[] {culture});
}
}
catch
{
// ignored
}
}
}