C# Winform Localization 질문

이번에 Winform으로 한국어,영어를 사용하는 프로젝트를 진행하였습니다.
폼에서 기본적으로 지원하는 Localizable = true로 사용하여 각 폼마다 resx파일을 언어 별로 생성하여
번역 본을 만들다 보니 폼이 많아질 수록 작업이 힘들어 지더라고요…
그리고 폼 디자인을 수정할 때마다 다른 언어의 resx파일은 수정이 되지 않아 일일이 복사하여 새로 붙여 넣는 식으로 작업하였습니다…

이후 프로젝트에서 지역화를 진행할 때는 전역의 리소스 파일로 관리하여야 할 듯한데…
각 컨트롤에 바인딩을 어찌 해야 할 지 모르겠네요… 하나하나 바인딩하는 코드를 직접 넣어야 하는 수 밖에 없나요?

다른 분들은 Winform에서 지역화를 어떻게 진행하는지 궁금합니다.

1 Like

저는 윈폼은 다루지 않지만, 가능한 한 모든 UI 앱을 한국어-영어로 만드는 편입니다.

이 것이 가능한 이유는 IStringLocalizer 라는 든든한 도구가 있기 때문입니다.
이 인터페이스의 구현 객체는 서비스 컨테이너에서 제공하는 것이라, 윈폼에서는 사용할 수 없을 것입니다.

윈폼의 지역화와 다른 도구를 사용했지만, 지역화를 하면서 느낀 점을 공유해드리겠습니다.

  1. 자원 파일 관리는 어렵다.

지역화 자원을 관리하는 것 자체가 쉬운 일은 아닙니다.
뷰 마다 지역화 파일을 만들어 보기도 하고, 전역적인 파일을 만들어 보기도 하고, 도메인 클래스 마다 지역화 파일을 만들기도 해봤지만, 방법 별로 큰 차이는 없었습니다.

  1. 짧은 문장보다는 긴 문장

한국어와 번역어 사이에 문자열 길이에 차이가 있기 마련입니다. 근데, 이 차이가 디자인 확정을 어렵게 합니다. 그래서 가급적 문자열을 길이를 맞추도록 노력했습니다. 예를 들어,

한: “삭제되면 복구할 수 없습니다.”
영: “Items will not be recoverable.”

추가:
이러한 길이 맞춤도, 외국어 폰트가 모노 스페이스(모든 문자의 폭이 같음)일 때 의미가 있지, 아니라면 부질없습니다.

그런데, 보통 위와 같은 짧은 문장은 길이를 맞추는 게 힘듭니다.
맞춘다 하더라도, 한국어든 번역어든 표현이 쉽게 어색해집니다.
또한, 이 허접한 결과를 위해, 투입되어야 하는 시간도 만만치 않습니다.

그래서, 메시지는 가급적 긴 문장으로 상정하고, 이를 위해 디자인도 넉넉히 고려하거나, 디자인과 무관한 시스템 메시지 박스를 적극 사용했습니다.

  1. 아이콘 + 툴팁.

콘트롤에 문자열을 입히는 것보다, 아이콘을 쓰는 것이 디자인 통일 측면에서 유리합니다.
설명이 필요한 경우, 콘트롤에 툴팁을 부여하고, 툴팁 메시지를 지역화 하는 것이죠.
VS 도 보시면, 생각보다 많은 툴팁을 적용하고 있음을 아실 것입니다.
문제는 아이콘은 개발 업무가 아니라 디자이너의 업무라는 점이죠.
디자이너가 없다면 아이콘 동냥 많이 다녀야 합니다.

  1. 개발 비용

보시면 아시겠지만, 지역화는 적지 않은 추가 업무를 유발합니다.
제 생각에는 지역화를 하겠다고 결정했으면, 반드시 추가 인력이 투입되어야 할 것 같습니다.
어설프게 했다간 디자인이 망가져 촌티가 나거나, 문자열 문제로 개발 기간이 굉장히 길어지거나, 미완성인 채로 출시하거나…

예산의 추가 투입이 없으면, 지역화가 독으로 작용할 수 있습니다.

3 Likes

현재 .net framework 4.8 winforms 프로젝트에 지역화 작업이 필요해서 작업을 진행했었는데요.

@hyeonjin 님 처럼 각 폼 별로 Localizable 속성을 통해 지역화 작업을 진행 했습니다.

winforms에서는 지역화 작업이 폼에 있는 Localizable 속성을 통해 Form.{locale}.resx 생성하고 Application에서 CultureInfo로 리소스 지역화 파일을 로드하는 수밖에 없는 것 같더라고요. (다른 방법이 있는지는 찾지 못했습니다.)

저는 지역화를 진행할 때 디자인 타임에서 관리되는 것들은 (Label.Text 등) Form.{locale}.resx로 관리를 하고 있고 런타임에서 지역화가 필요한 것들은(MessageBox 등) Resources 파일을 따로 만들어서 텍스트만 관리하고 있습니다. (Resources.{locale}.resx)

리소스에서 컨트롤 속성을 apply하는 순서가… 제가 분석한 것으로는 Form.{locale}.resx에 해당 컨트롤의 태그가 없으면 Form.resx에 있는 태그로 적용이 되는 것 같습니다.

해당 컨트롤 parent Form의 Language 속성이 (기본값)이 아닌 경우 속성을 수정하기만해도 Form.{locale}.resx에 수정된 속성으로 태그가 생기더라고요.

# Form.resx

<data name="button1.Location" type="System.Drawing.Point, System.Drawing">
     <value>240, 64</value>
  </data>
  <data name="button1.Text" xml:space="preserve">
    <value>테스트</value>
  </data>
# Form.ja.resx

# Parent Form Language 속성이 일본어인 경우 button1을 디자인 타임에서 위치 이동을 한 경우 생기게 됩니다.
<data name="button1.Location" type="System.Drawing.Point, System.Drawing">
    <value>326, 126</value>
  </data>
  <data name="button1.Text" xml:space="preserve">
    <value>테스또</value>
  </data>

그리고 폼 디자인을 수정할 때마다 다른 언어의 resx파일은 수정이 되지 않아 일일이 복사하여 새로 붙여 넣는 식으로 작업하였습니다…

한번이라도 수정된 속성이 있기 때문에 (기본값)에서 수정을 진행해도 Form.{locale}.resx가 아닌 Form.resx 태그 값이 바껴서 서로 다른 속성 값을 갖게 됩니다. 저도 컨트롤 위치를 바꿨는데 언어 별로 서로 다른 위치에 있어서 당황했었네요.

지역화라는 작업이… 이번에 winforms에서 처음 경험했는데 작업량이 만만치 않더라고요. 웹이나 다른 곳에서 .json이나 .yml 파일로 관리하는 것처럼 winforms은 .resx로 관리가 되는 것 같고, 이 노가다성? 작업은 어쩔 수 없는 것 같습니다.

그런데 가장 가장 큰 문제는 MR 시 코드 병합에서 resx가 충돌이 나는 경우인 것 같습니다. resx가 가끔 태그의 위치가 섞이게 되면서 충돌나는 경우가 있는데… 지옥을 맛봤습니다. :sob::sob:

1 Like