Friday, July 18, 2014

WPF globalization language, using resx file (WPF 다국어 작업, 쉬운 방법)

WPF로 다국어 작업을 해야 하는데 이것저것 검색해 보면 다음과 같은 것들을 접할 수 있다.

Resgen.exe
Al.exe
LocBaml.exe
msbuild.exe
uid

이것저것 검색해 봐도 쉽고 직관적으로 할 수 있는 방법은 없는 것 같고
뭔가 command line 명령으로 파일 생성하고 수정하고 해서 로딩해 오는 방법을 써야 한다.

결국 이런 방법들의 공통점은 아래와 같다.
1. resource 가 있는 파일이 있고
2. 내가 원하는 언어를 선택하여 언어에 맞게 resource를 로딩해 오면
3. 그걸 사용하는 것이다.
4. 그것도 정적으로!

이게 무엇인고 하니 시작하기 전에 System.Threading.Thread.CurrentUICulture를 세팅해서 쓰는 건 뭔 짓을 해도 공통이라는 것이다.

런타임시에 동적으로 언어 변경하는 건 다음 포스팅에서 설명하기로 하고
우선 정적으로라도 하는 방법, 그것도 쉽게 하는 방법을 써보자.

이것 만큼 쉽게 하는 방법은 없다고 본다.
(만약 있다면 제보 부탁!)

WPF이니 Window일 것이고 내 개발 환경은 다음과 같다.
OS: Windows 8.1
Framework: .NET Framework 4.5
Development Tool: Visual Studio Ultimate 2013
Language: C#
Project: WPF Application

<그냥 WPF 프로젝트 만들면 볼 수 있는 친숙한 화면>

이름을 ResourcesSample로 생성하면 기본적으로 위와 같은 화면이 나올 것이다.
여기서 부터 순서대로 해보면,

1. Add resource value in Resources.resx
이 파일을 열면 기본 리소스를 관리할 수 있는 엑셀 파일 같은게 나오는데 두 개를 추가해 본다.
String1=야옹, String2=멍멍

<Resource.resx 파일을 열면 리소스 관리가 가능하다>


2. Static binding text in MainWindow.xaml
리소스를 사용해 본다.
xmlns:res="clr-namespace:ResourcesSample.Properties"를 추가해 주고
TextBlock에 Text="{x:Static res:Resources.String1}"을
쓰면 디자인 타임에도 볼 수 있듯이 "야옹"이라는 글자가 잘 나온다.

<Design time에도 방금 추가한 리소스가 잘 바인딩이 되는 걸 볼 수 있다>

3. Change access modifier
그런데 실제 빌드해 보고 실행하려 하면 오류가 난다. 왜냐하면 String1은 internal 한정자라 public으로 바꿔줘야 하는데 아래 처럼 엑세스 한정자를 public으로 바꿔준다. String1뿐 아니라 Resource내에 모든 리소스가 public으로 변경 된다. 일단 실행은 잘 된다.

<엑세스 한정자를 public으로 변경한다. 그래야 String1의 키 값이 public으로 변경되고 접근할 수 있게 된다.>

<진짜 별거 없지만, 바인딩 된 "야옹" 텍스트가 잘 나오는게 확인 된다>


4. Add other Resource file
지금은 한국어용 리소스를 넣고 테스트 한 것이고, 영어 리소스를 넣어야 한다.
여기서 주의해야 할 것은 리소스 파일 이름을 CultureInfo 클래스의 Name대로 이름을 명명해야 한다는 것이다. 관련된 건 구글 좀 찾아보면 나오니 자세한 설명은 생략하겠다. 기존에 Resources.resx 파일과 같은 namespace 상에 있어야 하기 때문에 Resources.resx 파일을 Ctrl+C, Ctrl+V해서 추가한 뒤에 이름을 Resources.en-US.resx로 바꿔준다. 그리고 같은 String1, String2라는 이름을 가진 값을 "Yaong", "MeongMeong"으로 추가해 본다. 

<추가한 "Resources - 복사본.resx" 파일을 "Resources.en-US.resx"로 변경한다.>

5. Confirm output folder after build.
그리고 빌드를 해서 output 폴더(프로젝트 폴더의 bin/Debug/)를 보면 "en-US"라는 폴더가 생기고 그 안에 ResourcesSample.resources.dll 파일이 있는 걸 볼 수 있다.

<드디어 영어 리소스 파일이 생긴 것이다>
6. Set CultureInfo
그럼 마지막으로 App에 아래와 같은 코드를 추가한다.
이건 프로그램이 시작하기 전에 CultureInfo를 세팅하는 것인데 "en-US" 리소스를 추가했기 때문에 "en-US"로 생성한다.
그리고 CurrentUICulture에 세팅하면 모든 리소스가 우리가 추가한 언어의 리소스로 변경이 된다.
System.Threading.Thread.CurrentThread.CurrentUICulutre = new CultureInfo("en-US");

<CurrentUICulture에 "en-US"의 CultureInfo 객체를 세팅하면 끝이다>

<확인해 보면 별거 없지만, CurrentUICulture에 세팅한 대로 "Yaong" 텍스트가 나온다>

WPF 한 사람 치고 이 정도 했는데 다국어 못하겠다고 한 사람은 없을 것이다.
이후 작업은 이름-값에 해당하는 리소스들을 계속 추가해 주고 쓰는 것 뿐이다. 시간 싸움이라는 뜻이기도 하다.

그런데 다들 이런 식 -> 이런 식이라 함은 프로그램 시작시 리소스를 로딩해 와서 바인딩이 되는 식이라는 뜻이다. 런타임 시에 동적으로 되는 예제가 몇 있긴 한데 그것도 역시 리소스 파일을 가져와서 바꿔치기 하는 식이고 리소스 key-value를 메모리에 올려서 쓰겠다는 뜻이기도 하다.

다음 포스트에는 런타임시에 다국어 적용에 대해 써볼까 한다.


<한국어>
파일 다운로드 방법
- 링크를 눌러 새 창이 뜨면 ctrl+s를 누른다.
- 아니면 메뉴에 파일->다운로드를 클릭한다.

<English>
How to download to zip file.
- Link click, new tab opened -> press key 'ctrl+s'
- or File -> Download menu click.

2 comments:

  1. 감사합니다 덕분에 쉽게 세팅하는 방법 배웠습니다~~

    ReplyDelete
    Replies
    1. 6년 전에 쓴 글인데 댓글을 달아 주셔서 감사합니다.
      잘 배우셨다니 다행이네요.

      Delete