2021. 6. 2. 15:30

윈폼에서 다국어 처리 시 컨트롤에 자동으로 다국어를 바인딩시킬 수 있습니다.

 

연관글 영역

 

 

1. 개념 이해하기

자동으로 바인딩 되는 방식은 폼(Form) 단위로 관리됩니다.

 

'Language' 속성을 변경하면 자동으로 해당 언어-국가 코드에 맞게 '.resx'파일이 생성됩니다.

리소스(Resource)에서 다국어 처리할 때와 마찬가지로 '.resx'파일에 다국어 정보가 들어가게 되고,

설정된 현지화 정보에 따라 자동으로 처리됩니다. 

 

 

2. 폼(Form)에 현지화(Localizable) 처리

폼의 속성에 'Localizable'를 'True'로 바꿔줍니다.

 

 

이때 'Language'는 기본값인 '(Default)'여야 합니다.

여기서 '(Default)'는 중립언어(혹은 기본언어, 이하 기본언어)라고도 합니다.

지정된 언어의 내용을 찾지 못하면 자동으로 여기에 있는 값을 사용하게 됩니다.

 

이 샘플에서는 영어를 기본언어로 사용하겠습니다.

 

 

1. 기본언어('(Default)') 설정하기

폼에 다국어를 넣을 컨트롤들을 추가해 줍니다.

 

각 컨트롤의 Text를 입력해 줍니다.

입력이 다 되었으면 솔루션 탐색기에서 생성된 '.resx'파일을 열어 봅니다.

 

작성된 내용이 들어가 있는 것을 확인 할 수 있습니다.

 

이제 실행해보면 레이블에 영어가 표시됩니다.

 

 

1-2. 한국어 추가하기

'Language' 속성을 '한국어'로 바꿔줍니다.

 

 

각 컨트롤의 Text를 입력해 줍니다.

 

 

입력이 다 되었으면 솔루션 탐색기에서 생성된 '.resx'파일을 열어 봅니다.

 

한국어가 입력돼있는 것을 확인할 수 있습니다.

 

 

3. 언어 변경하기

이 방식은 폼의 UI가 불러오기 전에 문화권(Culture)설정을 해야 합니다.

'InitializeComponent();'가 호출되기 전에 설정해야 한다는 것입니다.

 

아래 코드를 폼의 생성자에 'InitializeComponent();' 위에 넣어 줍니다.

1
2
3
4
Thread.CurrentThread.CurrentCulture
    = new System.Globalization.CultureInfo("ko");
Thread.CurrentThread.CurrentUICulture
    = new System.Globalization.CultureInfo("ko");
cs

 

 

이제 실행을 하면 한국어가 표시됩니다.

"ko"를 "en"으로 바꾸면 다시 영어로 나옵니다.

 

 

4. 적용 타이밍

여기까지 따라왔다면 뭔가 이상함을 느끼셨을 겁니다.

"적용 타이밍이 폼이 생성될 때잖아!!!"

 

그렇습니다.

폼을 생성하기 전에 문화권을 설정해야 하고 이후로는 문화권을 다시 설정해도 적용되지 않습니다.

이것은 생성된'InitializeComponent()'코드를 보면 알 수 있습니다.

 

그럼 이제 "진실"을 알았으니 버튼 2개를 만들고 폼2를 여는 코드를 넣어줍시다.

폼2는 폼1처럼 다국어 설정을 해주시고 생성자를 아래와 같이 바꿔줍니다.

 

이제 실행해서 폼2를 열면 다음과 같이 적용되는 것을 알 수 있습니다.

 

 

프로그램을 재실행하여 적용하기

이쯤 되면 윈폼을 많이 다뤄본 사람이라면 다른 의문이 떠오릅니다.

"윈폼에서 시작폼을 닫으면 프로그램이 종료되는데....?"

 

이 방식으로 시작 폼에 다국어를 사용하면 프로그램을 재실행 시켜야만 적용됩니다.

그래서 외부 파일에 언어정보를 저장하고 프로그램을 재실행 시켜야 합니다.

 

이 기능은 각자 편한 대로 구현하면 됩니다.

이 프로젝트에서는 모델을 json으로 변환하여 저장합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/// <summary>
/// 설정파일 위치
/// </summary>
private readonly string _ConfigDir = "Config\\Config.json";
 
/// <summary>
/// 설정 내용
/// </summary>
private ConfigModel _Config = null;
 
/// <summary>
/// 설정 불러오기
/// </summary>
private void Config_Load()
{
    FileInfo fi = new FileInfo(this._ConfigDir);
    if(true == fi.Exists)
    {//파일 있다.
        //설정파일 읽어 들이기
        string sJson = System.IO.File.ReadAllText(this._ConfigDir);
 
        //모델이 바인딩
        this._Config = JsonConvert.DeserializeObject<ConfigModel>(sJson);
    }
    else
    {//파일 없다
        this._Config = new ConfigModel();
    }
}
 
/// <summary>
/// 설정 저장
/// </summary>
private void Config_Save()
{
    if(null == this._Config)
    {//설정이 없다.
        this._Config = new ConfigModel();
    }
 
    //리스트를 파일로 변환
    string sConfigJson = JsonConvert.SerializeObject(_Config);
 
    //파일에 저장
    System.IO.File.WriteAllText(
        this._ConfigDir
        , sConfigJson);
}
cs

 

저장 후  'Application.Restart();'를 호출하여 프로그램을 재실행 할 수 있습니다.

 

 

마무리

포스팅에 사용한 프로젝트 : github dang-gun/DotNetSamples - Localize_WinFormsLocalizeAuto

 

 

이전 글에서도 했던 이야기지만.....리소스를 통한 다국어 관리는 요즘 시대에는 좀 안 맞습니다.

표준화가 잘돼 있어서 관리하기는 편한데 협업하기에는 진짜 X같습니다.

 

리소스 단일 파일만으로도 이 모양인데 폼별로 리소스파일을 관리해야 하는 방식이라 더 불편하죠.

하지만 컨트롤들에 다국어를 지정하는 코드 없이 자동으로 바인딩되서 그런지 이 방식 쓰는 프로젝트를 간간이 보게 됩니다.

 

오픈소스에서 이런 짓을 하면 언어 추가할 때마다 빌드를 하든 기여를 하든 해야 하잖아!!