2014. 1. 14. 15:00

합성 컨트롤(Authoring a Composite Control)은 '유저 커스텀 컨트롤'과는 달리 DLL형태로 만들어wu 재사용이 쉽다는 장점이 있습니다.

예전엔 '유저 제작 컨트롤'같은 이름이였던거 같은데 기능이 바뀐 건지 처음 듣는 이름이네요.

개념상으로는 기존의 컨트롤들을 재조합하여 만들기 때문에 이런 이름을 붙인 것 같습니다.

 

간만에 그림하나 없는 MSDN의 샘플이 아무런 작업 없이 잘 돌아간 것 같네요 ㅋㅋㅋㅋ

그래서 MSDN의 샘플을 그대로 따라가도록 하겠습니다.

(참고 : MSDN - 연습: Visual C#에서 합성 컨트롤 제작)

 

 

1. 프로젝트 생성

C# > Windows > Windows Forms 컨트롤 라이브러리

를 선택하고 이름을 'ctlClockLib'으로 한 다음 프로젝트를 생성합니다.

 

 

2. 복합 컨트롤 만들기

이제 복합컨트롤을 만들겠습니다.

'ctlClockLib.cs'를 열어 디자인 코드를 확인합니다.

 

2-1. 컨트롤 추가

레이블과 타이머를 하나씩 추가하고 속성을 다음과 같이 설정합니다.

 

Label1

Name : lblDisplay

TestAlign : MiddleCenter

Font.Size : 14

 

 

timer1

Interval : 1000

Enabled : true

 

 

 

2-2. 코드 작성1

'timer1'을 더블 클릭하여

timer1_Tick(object sender, EventArgs e)

을 생성해 줍니다.

 

이 메소드는 나중에 재정의 할 것이기 때문에 한정자를 'protected'로 바꾸고 'virtual'키워드를 추가해 줍니다.

protected virtual void timer1_Tick(object sender, EventArgs e)
{
	lblDisplay.Text = DateTime.Now.ToLongTimeString();
}

 

 

2-3. 코드 작성2

'ctlClock.cs'의 코드로 들어가 다음과 같이 코드를 작성합니다.

public partial class ctlClock : UserControl
{
	private Color colFColor;
	private Color colBColor;


	public ctlClock()
	{
		InitializeComponent();
	}

	protected virtual void timer1_Tick(object sender, EventArgs e)
	{
		lblDisplay.Text = DateTime.Now.ToLongTimeString();
	}

	// Declares the name and type of the property.
	public Color ClockBackColor
	{
		// Retrieves the value of the private variable colBColor.
		get
		{
			return colBColor;
		}
		// Stores the selected value in the private variable colBColor, and 
		// updates the background color of the label control lblDisplay.
		set
		{
			colBColor = value;
			lblDisplay.BackColor = colBColor;
		}
	}
	// Provides a similar set of instructions for the foreground color.
	public Color ClockForeColor
	{
		get
		{
			return colFColor;
		}
		set
		{
			colFColor = value;
			lblDisplay.ForeColor = colFColor;
		}
	}

}

 

자신의 코드와 비교해가면서 한줄한줄 넣어 보아요~

 

 

3. 테스트

이제 빌드를 한후 실행해봅시다.

 

테스트용 컨테이너가 열리고 우리가 만든 코드가 동작하는 것을 볼 수 있습니다.

 

 

4. 복합컨트롤 상속하기

위에서 만든 복합컨트롤을 다시 다른 복합컨트롤에 추가하여 사용해 보겠습니다.

 

 

4-1. 새 복합 컨트롤 추가

솔루션 탐색기에서 'ctlClockLib'를 오른쪽 클릭합니다.

추가 > 새 항목 > Windows Forms > 상속된 사용자 정의 컨트롤

을 선택합니다.

이름은 'ctlAlarmClock'로 합니다.

 

상속 선택 화면에서 아까 우리가 만든 'ctlClock'를 선택합니다.

 

 

4-2. 기능 추가하기

이렇게 만들어진 상속된 복합 컨트롤에 다른 컨트롤들을 추가해 보겠습니다.

 

4-2-1. 속성 추가

'ctlAlarmClock'의 코드를 열어 클래스 안에 다음 코드를 추가합니다.

private DateTime dteAlarmTime;
private bool blnAlarmSet;
// These properties will be declared as public to allow future 
// developers to access them.
public DateTime AlarmTime
{
    get
    {
        return dteAlarmTime;
    }
    set
    {
        dteAlarmTime = value;
    }
}

public bool AlarmSet
{
    get
    {
        return blnAlarmSet;
    }
    set
    {
        blnAlarmSet = value;
    }
}

 

 

4-2-2. 디자인 추가

디자이너를 열어 레이블을 하나 추가합니다.

레이블의 속성은 다음과 같이 해줍니다.

 

Name : lblAlarm

Text : Alarm!

TextAlign : MiddleCenter

Visble : false

 

버튼도 하나 추가 합니다.

Name : btnAlarmOff

Text : Disable Alarm

 

 

 

4-2-3. 'timer1_Tick' 재정의

아까 우리는 'timer1_Tick'메소드를 버철(virtual)로 선언하였습니다.

이제 이것을 재정의하여 추가적인 동작을 하도록 만들겠습니다.

 

'private bool blnAlarmSet;'

위 코드를 찾아 그 아래 다음 코드를 추가합니다.

private bool blnColorTicker;

 

클래스의 맨 마지막에 다음 코드를 추가합니다.

protected override void timer1_Tick(object sender, System.EventArgs e)
{
	// Calls the Timer1_Tick method of ctlClock.
	base.timer1_Tick(sender, e);
	// Checks to see if the alarm is set.
	if (AlarmSet == false)
		return;
	else
	// If the date, hour, and minute of the alarm time are the same as
	// the current time, flash an alarm. 
	{
		if (AlarmTime.Date == DateTime.Now.Date && AlarmTime.Hour ==
			DateTime.Now.Hour && AlarmTime.Minute == DateTime.Now.Minute)
		{
			// Sets lblAlarmVisible to true, and changes the background color based on
			// the value of blnColorTicker. The background color of the label 
			// will flash once per tick of the clock.
			lblAlarm.Visible = true;
			if (blnColorTicker == false)
			{
				lblAlarm.BackColor = Color.Red;
				blnColorTicker = true;
			}
			else
			{
				lblAlarm.BackColor = Color.Blue;
				blnColorTicker = false;
			}
		}
		else
		{
			// Once the alarm has sounded for a minute, the label is made 
			// invisible again.
			lblAlarm.Visible = false;
		}
	}
}

 

 

이 코드에서 주의 깊게 봐야 할 것은

'base.timer1_Tick(sender, e);'

입니다.

 

우리가  'ctlClock'에서 만든 'timer1_Tick'을 재정의하면 원래 있던 'timer1_Tick'의 내용은 사라집니다.

원래 있던 내용도 실행하고 싶다면 위의 코드와 같이 'base'를 이용하여 원 코드에 접근해야 합니다.

 

 

4-2-4. 동작 해제 만들기

지금까지 만든 코드를 그대로 동작시키면 아직 아무런 동작을 하지 않습니다.

지금까지의 코드는 'AlarmTime'에 설정된 시간이 되면 'lblAlarm'이 깜박거리게 되어 있습니다.

'AlarmTime'는 외부에서 받아올 내용이기 때문에 아직 동작하지 않죠.

 

일단 알람이 동작하면 알람을 끌 수 있도록 위에서 해제 버튼을 'btnAlarmOff'으로 추가해놨습니다.

'btnAlarmOff'를 더블클릭하여 'btnAlarmOff_Click'이벤트를 생성합니다.

그리고 'btnAlarmOff_Click'이벤트에 다음 코드를 넣습니다.

 

private void btnAlarmOff_Click(object sender, EventArgs e)
{
	// Turns off the alarm.
	AlarmSet = false;
	// Hides the flashing label.
	lblAlarm.Visible = false;

}

 

 

5. 컨트롤을 테스트 폼에 추가하기

프로젝트를 빌드하고 기존솔루션에 'Windows Forms 응용 프로그램 ' 프로젝트를 추가합니다.

프로젝트 이름은 'test'로 합니다.

 

 

5-1. 참조 추가하기

위에서 만든 복합 컨트롤을 사용하기 위해서는 꼭 참조를 해야 합니다.

 

솔루션 탐색기 > '참조' 오른쪽 클릭 > 참조 추가

를 눌러 '프로젝트'탭에 있는 'ctlClockLib'를 선택하고 확인합니다.

 

참조됐다면 우리가 만든 복합 컨트롤이 보일 것입니다.

 

 

5-2. 테스트 프로그램 만들기

이제 'test'프로젝트에 있는 'Form1'에 'ctlAlarmClock' 컨트롤을 추가하고 'DateTimePicker'컨트롤과 레이블컨트롤을 하나씩 추가합니다.

 

dateTimePicker1

Name : dtpTest

Format : Time

 

label1

Name : lblTest

 

 

'dtpTest'을 더블클릭하여 'dtpTest_ValueChanged'이벤트를 생성합시다.

그리고 아래 코드를 넣습니다.

private void dtpTest_ValueChanged(object sender, EventArgs e)
{
	ctlAlarmClock1.AlarmTime = dtpTest.Value;
	ctlAlarmClock1.AlarmSet = true;
	lblTest.Text = "Alarm Time is " +
		ctlAlarmClock1.AlarmTime.ToShortTimeString();

}

 

 

 

5-3. 테스트하기

이제 'test'프로젝트를 시작 프로젝트로 설정하고 실행해봅시다.

프로그램이 시작되면 지금 있는 시간보다 1~2분 정도 뒤로 설정한 후 기다려 봅시다.

 

 

마무리

완성된 프로젝트입니다.

ctlClockLib.zip
다운로드

 

 

기초라면 기초인 내용인데 까먹을까 봐 정리해봤습니다.

복합 컨트롤을 이용하면 간편하게 원하는 기능들을 그룹화하여 관리할 수 있습니다.

이렇게 하면 자연스럽게 캡슐화도 돼서 프로젝트의 유지보수도 쉬워지죠 ㅎㅎㅎ