C#의 리소스는 모두 .resx 확장자를 가지는 XML 파일로 관리된다. 기존 Windows C/C++ 프로그래밍에서 .rc 파일을 컴파일 하여 .res의 바이너리 파일로 만들어 링크하던 것과는 많은 차이가 있는 것 같다. C#의 리소스는 리소스가 할당되는 위치에 따라 두 가지로 나뉘어지는데, 프로젝트 리소스 (Project Resource)와 로컬 리소스 (Local Resource)이다.
- 프로젝트 리소스 (Project Resource)
특징 : 프로젝트에 속해 있는 공유개념의 리소스이며, 주로 외부 파일로 관리된다.
장점 : 프로젝트 내에서는 리소스의 공유가 쉽다.
단점 : 프로젝트 리소스를 사용하는 폼을 복사할 때에는 사용하는 리소스도 함께 복사해 주어야 한다.
- 로컬 리소스 (Local Resource)
특징 : 폼 혹은 컨트롤에 속해 있는 리소스이다.
장점 : 폼이나 컨트롤의 소스를 복사할 때 리소스도 같이 복사되므로 모듈화가 쉽다.
단점 : 같은 리소스를 여러 폼에서 사용할 때 중복 포함되어 낭비가 발생한다.
어떤 폼이나 컨트롤에서 리소스를 지정하려 하면 다음의 그림과 같이 리소스 유형을 고르도록 한다. (예를 들어, 버튼의 이미지를 지정하는 등의 방법을 말한다.)
리소스 파일(.resx)의 형식은 XML 형태이지만 내부에 포함하는 형식에는 다음과 같이 약간의 차이가 있다.
- 프로젝트 리소스 (Project Resource)
- 위치 : Properties / Resources.resx 파일 (다음의 왼쪽 그림 참조)
- 내부 : 리소스에 대한 설명 (리소스 이름, 리소스 유형, 외부 파일이름 등)이 기록
(단, 문자열 리소스는 Resources.resx 파일에 직접 기록) - 위의 그림에서 프로젝트 리소스를 선택하는 경우에는 필요한 리소스를 새로 생성하거나 기존 리소스를 선택하여 사용할 수 있음
- 로컬 리소스 (Local Resource)
- 위치 : Form1.cs / Form1.resx 파일 (다음의 오른쪽 그림 참조)
- 내부 : 프로젝트 리소스와는 달리 모든 리소스의 바이너리 값도 Form1.resx 파일에 직접 기록
- 위의 그림에서 로컬 리소스를 선택하는 경우에는 필요한 리소스의 중복여부와 관계없이 항상 새로 리소스를 생성한다.
각 리소스들은 프로그램 작성시 통합환경에서 버튼과 같은 컨트롤의 이미지를 지정하여 사용할 수도 있으며, 여기서 설명하려고 하는 실행 시 로드/지정할 수도 있다. 통합환경에서 지정하는 것은 매우 쉽기 때문에 여기서는 설명을 생략한다. 다음에는 실행 시에 동적으로 리소스를 로드하고 지정하는 방법을 설명한다.
(1) 프로젝트 리소스 직접 지정하기
프로젝트 리소스는 다음과 같이 컴파일 시에 직접 지정되도록 할 수 있다.
1
2
3
4
5
6 |
private void button3_Click( object sender, EventArgs e) {
// direct name indicating for global resources
pictureBox1.Image = Properties.Resources.Image1;
pictureBox2.Image = Properties.Resources.Image2; } |
이것은 다음의 그림과 같이 프로젝트 리소스 생성시에 Resources라는 클래스를 만들어 해당 리소스의 이름으로 속성 (Property)를 만들어 주기 때문이다.
지정하고자 하는 리소스는 <Project Namespace>.Properties 네이스페이스의 Resources 클래스의 정적 속성 (static property)로 선언되어 있다.
(2) 프로젝트 리소스 실행 시 로드하기
실행 시에 프로젝트 리소스를 로드하기 위해서는 System.Resources.ResourceManager 클래스를 이용한다. ResourceManager 객체 생성 시에 리소스의 루트이름과 어셈블리를 지정하고, ResourceManager 객체의 GetObject( ) 메서드를 이용하여 리소스를 로드한다. 프로젝트 리소스의 루트이름은 다음과 같다.
“<Assembly Name>.Properties.Resources”
다음의 C# 코드를 보면 좀 더 이해하기 쉬울 것이다.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20 |
using System.Resources; // ResourceManager ... ... protected object LoadProjectResource( string strResName) {
Assembly assembly = Assembly.GetExecutingAssembly();
string strBaseName = assembly.GetName().Name + "." + "Properties.Resources" ;
// strBaseName = "csharp_ResourceTest.Properties.Resources";
ResourceManager rm = new ResourceManager(strBaseName, assembly);
return rm.GetObject(strResName); // load resource from item name } private void button4_Click( object sender, EventArgs e) {
...
pictureBox1.Image = (Image) LoadProjectResource( "Image1" );
... } |
(3) 로컬 리소스 실행 시 로드하기
앞에서도 설명했지만, 로컬 리소스는 폼이나 컨트롤에 속해 있는 리소스이다. 실행 시에 로컬 리소스를 로드하기 위해서는 프로젝트 리소스와 같이 System.Resources.ResourceManager 클래스를 이용한다. ResourceManager 객체 생성 시에 해당 폼의 타입을 지정하고, ResourceManager 객체의 GetObject( ) 메서드를 이용하여 리소스를 로드한다. 다음 C# 코드는 로컬 리소스를 로드하는 예제는 다음과 같다.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17 |
using System.Resources; // ResourceManager ... ... protected object LoadFormResource( string strResName) {
ResourceManager rm = new ResourceManager( this .GetType());
return rm.GetObject(strResName);
// load resource from item name } private void button4_Click( object sender, EventArgs e) {
// indirect load local resource
Image image2 = (Image) LoadFormResource( "button1.Image" );
pictureBox2.Image = image2; } |
어떤 형식의 리소스를 사용하고 어떻게 로드 하는지는 정답이 있는 것이 아니라 각 상황에 맞추어 결정해야 할 것이다.
'프로그래밍 > .Net' 카테고리의 다른 글
DataGridView 소개 (0) | 2014.01.17 |
---|---|
DataGridView내에서 Combobox 활용 (0) | 2014.01.17 |
해시코드로 알아본 string의 메모리 저장방법 (0) | 2014.01.17 |
장치관리자 USB 정보 list 가져오기 (0) | 2014.01.17 |
Key Event 키 이벤트 발생 안될 때 (0) | 2014.01.17 |