다음을 통해 공유


연습: Visual C#에서 합성 컨트롤 제작

업데이트: 2007년 11월

복합 컨트롤을 사용하면 사용자 지정 그래픽 인터페이스를 만들고 다시 사용할 수 있습니다. 복합 컨트롤은 본질적으로 시각적 표시를 가진 구성 요소입니다. 그러므로 사용자 정의 컨트롤은 하나 이상의 Windows Form 컨트롤이나 구성 요소로 구성될 수도 있고 사용자 입력을 검증하거나 표시 속성을 수정하거나 제작자가 요구하는 다른 작업을 수행함으로써 기능을 확장할 수 있는 코드 블록으로 구성될 수도 있습니다. 복합 컨트롤은 다른 컨트롤과 마찬가지 방법으로 Windows Form에 배치될 수 있습니다. 이 연습의 첫 번째 부분에서는 ctlClock이라는 간단한 복합 컨트롤을 만듭니다. 이 연습의 두 번째 부분에서는 상속을 통해 ctlClock의 기능을 확장합니다.

참고:

실제 설정이나 버전에 따라서 화면에 나타나는 대화 상자와 메뉴 명령이 도움말의 설명과 다를 수 있습니다. 설정을 변경하려면 도구 메뉴에서 설정 가져오기 및 내보내기를 선택합니다. 자세한 내용은 Visual Studio 설정을 참조하십시오.

프로젝트 만들기

새 프로젝트를 만들 때는 이름에서 루트 네임스페이스, 어셈블리 이름 및 프로젝트 이름을 설정하도록 지정하여 기본 구성 요소가 올바른 네임스페이스에 놓이도록 해야 합니다.

ctlClockLib 컨트롤 라이브러리 및 ctlClock 컨트롤을 만들려면

  1. 파일 메뉴에서 새로 만들기를 가리킨 다음 프로젝트를 클릭하여 새 프로젝트 대화 상자를 표시합니다.

  2. Visual C# 프로젝트의 목록에서 Windows 컨트롤 라이브러리 프로젝트 템플릿을 선택하고 이름 상자에 ctlClockLib를 입력한 다음 확인을 클릭합니다.

    기본적으로 프로젝트 이름인 ctlClockLib도 루트 네임스페이스에 할당됩니다. 루트 네임스페이스는 어셈블리에서 구성 요소의 이름을 한정하는 데 사용됩니다. 예를 들어, 두 어셈블리에서 ctlClock이라는 구성 요소를 제공하는 경우 ctlClockLib.ctlClock.을 사용하여 ctlClock 구성 요소를 지정할 수 있습니다.

  3. 솔루션 탐색기에서 UserControl1.cs를 마우스 오른쪽 단추로 클릭한 다음 이름 바꾸기를 클릭합니다. 파일 이름을 ctlClock.cs로 변경합니다. 모든 참조의 이름을 코드 요소 "UserControl1"로 바꿀지 여부를 묻는 메시지가 나타나면 예 단추를 클릭합니다.

    참고:

    기본적으로 복합 컨트롤은 시스템에서 제공하는 UserControl 클래스에서 상속됩니다. UserControl 클래스는 모든 복합 컨트롤에서 요구하는 기능을 제공하며 표준 메서드 및 속성을 구현합니다.

  4. 파일 메뉴에서 모두 저장을 클릭하여 프로젝트를 저장합니다.

복합 컨트롤에 Windows 컨트롤 및 구성 요소 추가

시각적 인터페이스는 복합 컨트롤의 필수적인 부분입니다. 이 시각적 인터페이스는 디자이너 화면에 하나 이상의 Windows 컨트롤을 추가하여 구현할 수 있습니다. 아래 데모에서는 Windows 컨트롤을 복합 컨트롤에 결합한 다음 코드를 작성하여 기능을 구현합니다.

Label 및 Timer를 복합 컨트롤에 추가하려면

  1. 솔루션 탐색기에서 ctlClock.cs를 마우스 오른쪽 단추로 클릭한 다음 디자이너 보기를 클릭합니다.

  2. 도구 상자에서 공용 컨트롤 노드를 확장한 다음 Label을 두 번 클릭합니다.

    label1이라는 Label 컨트롤이 디자이너 화면에 있는 컨트롤에 추가됩니다.

  3. 디자이너에서 Label1을 클릭합니다. 속성 창에서 다음 속성을 설정합니다.

    속성

    다음으로 변경

    Name

    lblDisplay

    Text

    (공백)

    TextAlign

    MiddleCenter

    Font.Size

    14

  4. 도구 상자에서 구성 요소 노드를 확장한 다음 Timer를 두 번 클릭합니다.

    Timer는 구성 요소이므로 런타임에 시각적으로 표시되지 않습니다. 따라서 디자이너 화면에 컨트롤과 함께 나타나지 않고 구성 요소 디자이너(디자이너 화면의 아래쪽에 있는 트레이)에 나타납니다.

  5. 구성 요소 디자이너에서 timer1을 클릭한 다음 Interval 속성은 1000으로, Enabled 속성은 true로 설정합니다.

    Interval 속성은 Timer 구성 요소가 작동하는 빈도를 제어합니다. timer1이 작동할 때마다 timer1_Tick 이벤트의 코드가 실행됩니다. 간격은 한 동작과 다음 동작 사이의 시간을 1/1000초 단위로 나타냅니다.

  6. 구성 요소 디자이너에서 timer1을 두 번 클릭한 다음 ctlClock의 timer1_Tick 이벤트로 이동합니다.

  7. 코드를 다음 코드 샘플과 비슷하게 수정합니다. 액세스 한정자를 반드시 private에서 protected로 변경합니다.

    [C#]

    protected void timer1_Tick(object sender, System.EventArgs e)
    {
        // Causes the label to display the current time.
        lblDisplay.Text = DateTime.Now.ToLongTimeString(); 
    }
    

    이 코드에서는 현재 시간이 lblDisplay에 표시되도록 합니다. timer1의 간격이 1000으로 설정되었기 때문에 이 이벤트는 1000밀리초(1초)마다 발생하여 현재 시간을 매초 업데이트합니다.

  8. 메서드에 대해 virtual 키워드를 사용하여 재정의 가능하도록 수정합니다. 자세한 내용은 아래의 "복합 컨트롤로부터 상속" 단원을 참조하십시오.

    protected virtual void timer1_Tick(object sender, System.EventArgs e)
    
  9. 파일 메뉴에서 모두 저장을 클릭하여 프로젝트를 저장합니다.

복합 컨트롤에 속성 추가

이제 클럭 컨트롤에서는 자체적으로 기본적인 속성 집합을 가진 Label 컨트롤과 Timer 구성 요소를 캡슐화합니다. 이들 컨트롤의 개별 속성은 다른 사용자가 액세스할 수 없지만 적절한 코드 블록을 작성하여 사용자 지정 속성을 만들어 노출할 수 있습니다. 다음 절차에서는 사용자가 배경색과 텍스트 색을 변경할 수 있도록 해주는 속성을 컨트롤에 추가합니다.

복합 컨트롤에 속성을 추가하려면

  1. 솔루션 탐색기에서 ctlClock.cs를 마우스 오른쪽 단추로 클릭하고 코드 보기를 클릭합니다.

    컨트롤에 대해 코드 편집기가 열립니다.

  2. public partial class ctlClock 문을 찾아 여는 중괄호({) 아래에 다음 코드를 입력합니다.

    [C#]

    private Color colFColor;
    private Color colBColor;
    

    이들 문은 앞으로 만들 속성 값을 저장하는 데 사용할 개인 변수를 만듭니다.

  3. 2단계의 변수 선언 아래에 다음 코드를 입력합니다.

    [C#]

    // 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;
        }
    }
    

    위의 코드는 두 개의 사용자 지정 속성인 ClockForeColor 및 ClockBackColor를 만들며, 이 속성은 이후 이 컨트롤의 사용자들이 사용할 수 있습니다. get 및 set 문은 속성 값을 저장하고 검색할 뿐만 아니라 속성의 해당 기능을 구현하는 코드를 제공하기도 합니다.

  4. 파일 메뉴에서 모두 저장을 클릭하여 프로젝트를 저장합니다.

컨트롤 테스트

컨트롤은 독립 실행형 응용 프로그램이 아니며 컨테이너에서 호스팅되어야 합니다. 컨트롤의 런타임 동작을 테스트하고 UserControl Test Container를 사용하여 해당 속성을 실행해 봅니다. 자세한 내용은 방법: UserControl의 런타임 동작 테스트를 참조하십시오.

컨트롤을 테스트하려면

  1. F5 키를 눌러 프로젝트를 빌드하고 UserControl Test Container에서 컨트롤을 실행합니다.

  2. 테스트 컨테이너의 속성 표에서 ClockBackColor 속성을 찾은 다음 이 속성을 선택하여 색상표를 표시합니다.

  3. 원하는 색을 클릭하여 선택합니다.

    컨트롤의 배경색이 선택한 색으로 변경됩니다.

  4. 비슷한 이벤트 순서를 사용하여 ClockForeColor 속성이 예상한 대로 작동하는지 확인합니다.

    이 단원 및 이전 단원에서는 구성 요소 및 Windows 컨트롤을 코드와 결합하여 복합 컨트롤 형태로 사용자 지정 기능을 제공하도록 패키지로 만드는 방법을 설명했습니다. 복합 컨트롤의 속성을 노출하는 방법과 이를 완료한 후 컨트롤을 테스트하는 방법을 설명했습니다. 다음 단원에서는 ctlClock을 기본으로 하여 상속된 복합 컨트롤을 만드는 방법에 대해 설명합니다.

복합 컨트롤로부터 상속

이전 단원에서는 Windows 컨트롤, 구성 요소 및 코드를 다시 사용할 수 있는 복합 컨트롤로 결합하는 방법을 설명했습니다. 이제 이 복합 컨트롤을 다른 컨트롤을 만들 수 있는 기본 컨트롤로 사용할 수 있습니다. 기본 클래스에서 클래스를 파생시키는 프로세스를 상속이라고 합니다. 이 단원에서는 ctlAlarmClock이라는 복합 컨트롤을 만듭니다. 이 컨트롤은 부모 컨트롤인 ctlClock에서 파생됩니다. 부모 메서드를 재정의하고 새 메서드 및 속성을 추가하여 ctlClock의 기능을 확장하는 방법을 설명합니다.

상속된 컨트롤을 만드는 첫 번째 단계는 부모로부터 파생시키는 것입니다. 이렇게 하면 부모 컨트롤의 모든 속성, 메서드 및 그래픽 특성을 갖는 새 컨트롤이 만들어지지만 이 컨트롤을 새 기능이나 수정된 기능을 추가할 기본 컨트롤로 사용할 수도 있습니다.

상속된 컨트롤을 만들려면

  1. 솔루션 탐색기에서 ctlClockLib를 마우스 오른쪽 단추로 클릭하고 추가를 가리킨 다음 사용자 정의 컨트롤을 클릭합니다.

    새 항목 추가 대화 상자가 열립니다.

  2. 상속된 사용자 정의 컨트롤 템플릿을 선택합니다.

  3. 이름 상자에 ctlAlarmClock.cs를 입력한 다음 추가를 클릭합니다.

    상속 선택 대화 상자가 열립니다.

  4. 구성 요소 이름 아래에서 ctlClock을 두 번 클릭합니다.

  5. 솔루션 탐색기에서 현재 프로젝트를 찾아봅니다.

    참고:

    ctlAlarmClock.cs라는 파일이 현재 프로젝트에 추가되었습니다.

경보 속성 추가

복합 컨트롤에 속성을 추가하는 것과 같은 방법으로 상속된 컨트롤에도 속성을 추가합니다. 이제 속성 선언 구문을 사용하여 컨트롤에 다음 두 개의 속성을 추가합니다. 즉, 경보가 꺼지는 날짜와 시간 값이 저장되는 AlarmTime과 경보 설정 여부를 나타내는 AlarmSet입니다.

복합 컨트롤에 속성을 추가하려면

  1. 솔루션 탐색기에서 ctlAlarmClock을 마우스 오른쪽 단추로 클릭한 다음 코드 보기를 선택합니다.

  2. public class 문을 찾아 컨트롤은 ctlClockLib.ctlClock에서 상속되어야 합니다. 여는 중괄호({) 문 아래에 다음 코드를 입력합니다.

    [C#]

    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;
        }
    }
    

컨트롤의 그래픽 인터페이스에 추가

상속받은 컨트롤은 이 컨트롤을 상속해 준 컨트롤과 같은 시각적 인터페이스를 가집니다. 상속받은 컨트롤은 부모 컨트롤과 같은 구성 요소 컨트롤을 가지지만 이들 구성 요소 컨트롤의 속성은 명시적으로 노출되어야 사용 가능해집니다. 복합 컨트롤에 추가하는 것과 같은 방법으로 상속된 복합 컨트롤의 그래픽 인터페이스에도 추가할 수 있습니다. 경보 클럭의 시각적 인터페이스에 계속 추가하기 위해 경보 소리가 날 때마다 깜박이는 Label 컨트롤을 추가할 것입니다.

Label 컨트롤을 추가하려면

  1. 솔루션 탐색기에서 ctlAlarmClock을 마우스 오른쪽 단추로 클릭한 다음 디자이너 보기를 클릭합니다.

    주 창에 ctlAlarmClock에 대한 디자이너가 열립니다.

  2. 컨트롤이 표시된 부분을 클릭하여 속성 창을 살펴 봅니다.

    참고:

    모든 속성이 표시될 때는 흐리게 표시됩니다. 즉, 이러한 속성은 lblDisplay의 기본 속성이기 때문에 속성 창에서 수정하거나 액세스할 수 없습니다. 기본적으로 복합 컨트롤에 들어 있는 컨트롤은 private이며 그 속성에는 어떠한 방법으로도 액세스할 수 없습니다.

    참고:

    복합 컨트롤의 이후 사용자가 내부 컨트롤에 액세스할 수 있도록 하려면 해당 컨트롤을 public 또는 protected로 선언하십시오. 이렇게 하면 복합 컨트롤에 포함된 컨트롤의 속성을 적절한 코드를 사용하여 설정하거나 수정할 수 있습니다.

  3. 복합 컨트롤에 Label 컨트롤을 추가합니다.

  4. 마우스를 사용하여 Label 컨트롤을 표시 상자 바로 아래로 끌어 옵니다. 속성 창에서 다음 속성을 설정합니다.

    속성

    설정값

    Name

    lblAlarm

    Text

    Alarm!

    TextAlign

    MiddleCenter

    Visible

    false

경보 기능 추가

이전 절차에서 복합 컨트롤에서 경보 기능을 활성화하는 속성 및 컨트롤을 추가했습니다. 이 절차에서는 현재 시간과 경보 시간을 비교하여 시간이 같을 경우 경보 깜박임을 생성하는 코드를 추가합니다. ctlClock의 timer1_Tick 메서드를 재정의하고 코드를 추가하면 ctlClock의 기본 기능은 유지한 채 ctlAlarmClock의 기능을 확장할 수 있습니다.

ctlClock의 timer1_Tick 메서드를 재정의하려면

  1. 코드 편집기에서 private bool blnAlarmSet; 문을 찾습니다. 이 문 바로 아래에 다음 문을 추가합니다.

    [C#]

    private bool blnColorTicker;
    
  2. 코드 편집기에서 클래스 끝에 있는 닫기 괄호(})를 찾습니다. 괄호 바로 앞에 다음 코드를 추가합니다.

    [C#]

    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;
            }
        }
    }
    

    이 코드를 추가하면 몇 가지 작업을 수행할 수 있습니다. override 문은 컨트롤에게 기본 컨트롤에서 상속된 메서드 대신 이 메서드를 사용하도록 지시합니다. 이 메서드는 호출될 경우 base.timer1_Tick 문을 호출하여 재정의되는 메서드를 호출하고 원본 컨트롤에 포함된 모든 기능이 이 컨트롤에서 재생성되도록 합니다. 그런 다음 추가 코드를 실행하여 경보 기능을 결합합니다. 경보 소리가 나면 깜박이는 레이블 컨트롤이 나타납니다.

    경보 클럭 컨트롤이 거의 완성되었습니다. 남은 작업은 경보 해제 방법을 구현하는 것입니다. 이 작업을 하려면 lblAlarm_Click 메서드에 코드를 추가합니다.

경보 해제 메서드를 구현하려면

  1. 솔루션 탐색기에서 ctlAlarmClock.cs를 마우스 오른쪽 단추로 클릭한 다음 디자이너 보기를 클릭합니다.

    디자이너가 열립니다.

  2. 컨트롤에 단추를 추가합니다. 단추의 속성을 다음과 같이 설정합니다.

    속성

    Name

    btnAlarmOff

    Text

    Disable Alarm

  3. 디자이너에서 btnAlarmOff를 두 번 클릭합니다.

    private void btnAlarmOff_Click 줄에 대해 코드 편집기가 열립니다.

  4. 이 메서드를 다음 코드와 비슷하게 수정합니다.

    [C#]

    private void btnAlarmOff_Click(object sender, System.EventArgs e)
    {
        // Turns off the alarm.
        AlarmSet = false;
        // Hides the flashing label.
        lblAlarm.Visible = false;
    }
    
  5. 파일 메뉴에서 모두 저장을 클릭하여 프로젝트를 저장합니다.

폼에서 상속된 컨트롤 사용

기본 클래스 컨트롤인 ctlClock을 테스트한 것과 같은 방법으로 상속된 컨트롤을 테스트할 수 있습니다. F5 키를 눌러 프로젝트를 빌드하고 UserControl Test Container에서 컨트롤을 실행합니다. 자세한 내용은 방법: UserControl의 런타임 동작 테스트를 참조하십시오.

컨트롤을 배치하여 사용하려면 폼에서 컨트롤을 호스팅해야 합니다 표준 복합 컨트롤과 마찬가지로 상속된 복합 컨트롤은 독립 실행형이 아니며 폼이나 다른 컨테이너에서 호스팅되어야 합니다. ctlAlarmClock의 기능은 복잡하므로 이를 테스트하려면 추가 코드가 필요합니다. 이 절차에서는 간단한 프로그램을 작성하여 ctlAlarmClock의 기능을 테스트합니다. ctlAlarmClock의 AlarmTime 속성을 설정하고 표시하는 코드를 작성하여 기본 기능을 테스트합니다.

컨트롤을 빌드하고 테스트 폼에 추가하려면

  1. 솔루션 탐색기에서 ctlClockLib를 마우스 오른쪽 단추로 클릭하고 빌드를 클릭합니다.

  2. 새 Windows 응용 프로그램 프로젝트를 솔루션에 추가하고 Test로 명명합니다.

  3. 솔루션 탐색기에서 테스트 프로젝트에 대한 참조 노드를 마우스 오른쪽 단추로 클릭합니다. 참조 추를 클릭하여 참조 추가 대화 상자를 표시합니다. 프로젝트라는 레이블이 붙은 탭을 클릭합니다. ctlClockLib 프로젝트가 프로젝트 이름 아래에 나열됩니다. 프로젝트를 두 번 클릭하여 해당 참조를 테스트 프로젝트에 추가합니다.

  4. 솔루션 탐색기에서 Test를 오른쪽 마우스 단추로 클릭하고 빌드를 클릭합니다.

  5. 도구 상자에서 ctlClockLib Components 노드를 확장합니다.

  6. ctlAlarmClock을 두 번 클릭하여 ctlAlarmClock 복사본을 폼에 추가합니다.

  7. 도구 상자에서 DateTimePicker를 찾아 두 번 클릭하여 DateTimePicker 컨트롤을 폼에 추가하고 Label을 두 번 클릭하여 Label 컨트롤을 추가합니다.

  8. 마우스를 사용하여 폼에서 편리한 위치에 컨트롤을 배치합니다.

  9. 이러한 컨트롤의 속성을 다음과 같은 방법으로 설정합니다.

    컨트롤

    속성

    label1

    Text

    (공백)

     

    Name

    lblTest

    dateTimePicker1

    Name

    dtpTest

     

    Format

    Time

  10. 디자이너에서 dtpTest를 두 번 클릭합니다.

    private void dtpTest_ValueChanged에 대해 코드 편집기가 열립니다.

  11. 코드를 다음과 비슷하게 수정합니다.

    [C#]

    private void dtpTest_ValueChanged(object sender, System.EventArgs e)
    {
        ctlAlarmClock1.AlarmTime = dtpTest.Value;
        ctlAlarmClock1.AlarmSet = true;
        lblTest.Text = "Alarm Time is " +
            ctlAlarmClock1.AlarmTime.ToShortTimeString();
    }
    
  12. 솔루션 탐색기에서 Test를 마우스 오른쪽 단추로 클릭하고 시작 프로젝트로 설정을 클릭합니다.

  13. 디버그 메뉴에서 디버깅 시작을 클릭합니다.

    테스트 프로그램이 시작됩니다. 현재 시간이 ctlAlarmClock 컨트롤에서 업데이트되고 시작 시간이 DateTimePicker 컨트롤에 표시됩니다.

  14. 분이 표시되는 DateTimePicker를 클릭합니다.

  15. 키보드를 사용하여 ctlAlarmClock에 표시된 현재 시간보다 1분 빠른 분 값을 설정합니다.

    경보 설정 시간이 lblTest에 표시됩니다. 표시된 시간이 경보 설정 시간에 도달할 때까지 기다립니다. 표시된 시간이 경보가 설정된 시간에 도달하면 lblAlarm이 깜박입니다.

  16. btnAlarmOff을 클릭하여 경보를 해제합니다. 경보를 다시 설정할 수 있습니다.

    이 연습에서는 주요 개념을 많이 다루었습니다. 컨트롤과 구성 요소를 복합 컨트롤 컨테이너에 결합하여 복합 컨트롤을 만드는 방법을 설명했습니다. 컨트롤에 속성을 추가하고 사용자 지정 기능을 구현하는 코드를 작성하는 방법을 설명했습니다. 마지막 단원에서는 상속을 통해 주어진 복합 컨트롤의 기능을 확장하고 호스트 메서드를 재정의하여 그 기능을 변경하는 방법을 설명했습니다.

참고 항목

작업

방법: 도구 상자 사용자 지정 대화 상자에 컨트롤 표시

연습: Visual C#을 사용하여 Windows Forms 컨트롤에서 상속

방법: 식별자 이름 바꾸기

개념

사용자 지정 컨트롤의 종류

기타 리소스

구성 요소를 사용한 프로그래밍

구성 요소 제작 연습