본문 바로가기
다물칸 주소복사
조회 수 4797 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
Extra Form
구분 팁&트릭
출처 http://www.rustican.com/board/zboard.php?id=paper&no=161

 

예제에서는 버튼을 사용했는데 사용자 정의 컨트롤로 만든 것도 되는 것을 확인하였다.

그냥 배열 선언해서는 안되고 이렇게 해야 잘된다.

 

 

Visual Basic .NET과 Visual C# .NET에서 컨트롤 배열 구현

Matthew A. Stoecker
 

 

요약: 이 백서에서는 Visual Basic? .NET과 Visual C#™ .NET을 사용하여 컨트롤 배열을 만들고 관리하는 방법을 보여 줍니다(11페이지/인쇄 페이지 기준).

목차

소개
사전 요구 사항
프로젝트 만들기
컬렉션 구현
컨트롤 배열 노출
공통 이벤트 처리기 만들기
프로젝트 테스트
결론

소개

배열을 사용하면 공통 기능을 공유하는 컨트롤 그룹에 대한 작업을 쉽게 할 수 있습니다. 예를 들어 컨트롤 그룹은 클릭할 때 연결된 데이터를 표시하거나 연결된 동작을 제공하는 데 사용할 수 있습니다. Visual Basic .NET과 C#에서는 컨트롤 배열을 만들 수 없지만 컨트롤 배열이 제공하는 모든 기능을 프로그래밍 방식으로 복제할 수는 있습니다. 이 기사에서는 컨트롤 배열의 기능을 복제하는 단순한 구성 요소를 만드는 과정을 다룹니다.

컨트롤 배열의 몇 가지 유용한 측면은 다음과 같습니다.

  • 인덱스로 같은 이름의 컨트롤 집합을 액세스함으로써 번호로 속성을 검색 및 설정하고 배열의 모든 컨트롤 내에서 반복할 수 있도록 합니다. 일반적으로 이렇게 하려면 다음 구문을 사용합니다.
    ' Visual Basic 의사 코드
    MyControl(myIndex).MyProperty = myValue
    MyControl(myIndex + 1).MyMethod
    
    // C# 의사 코드
    myControl[myIndex].myProperty = myValue;
    myControl[myIndex + 1].myMethod
  • 다음 예제와 같이 단일 이벤트 처리기로 여러 컨트롤의 이벤트를 처리하고, 이 이벤트의 인덱스를 검색하여 사용합니다.
    ' Visual Basic 의사 코드
    Private Sub MyControl_Click(sender as Object, e as EventArgs)
       Messagebox.Show("MyControl 번호를 클릭했습니다. " & _
          MyControl.Index)
    End Sub
    
    // C# 의사 코드
    private void myControl_Click(System.Object sender, System.EventArgs e)
       {
          Messagebox.Show("MyControl 번호를 클릭했습니다. " +
             MyControl.Index);
       }
  • 다음과 같이 런타임에 컨트롤을 동적으로 추가하거나 제거합니다.
    ' Visual Basic 의사 코드
    Dim i as Integer
    For i = 1 to 5
       ' 컨트롤을 만들고 속성에 값을 할당하는 코드를 삽입합니다. 
    Next i
    
    // C# 의사 코드
    for (int i = 1; i < 6; i++)
    {
       // 컨트롤을 만들고 속성에 값을 할당하는 코드를 삽입합니다.  
    }

Visual Basic .NET과 C#을 사용하면 이 기능 중 일부(예: 대리자를 사용하여 여러 컨트롤의 이벤트를 단일 이벤트 처리기에 바인딩)를 복제할 수 있습니다. 그러나 관리하기 쉬운 동적 구성 요소 하나에 해당 기능을 통합하면 더 편리합니다. 이 기사에서는 다음을 사용하는 구성 요소를 만드는 방법에 대해 다룹니다.

  • 컨트롤을 인덱싱하고 정렬하는 컬렉션. 데모로 단추 컬렉션을 사용합니다.
  • 파생한 단추의 클릭 이벤트를 처리하는 이벤트 처리기
  • 컨트롤 및 그 멤버를 인덱스로 참조할 수 있도록 하는 코드
  • 폼에서 컨트롤을 동적으로 추가 및 제거하는 코드

사전 요구 사항

  • 구성 요소와 그 작동 방법에 대해 잘 알고 있어야 합니다.
  • 다형성에 대해 어느 정도 알고 있어야 합니다. 자세한 내용은 Polymorphism in Components 를 참조하십시오.
  • Visual Basic .NET 구문이나 C# .NET 구문을 이해해야 합니다.

프로젝트 만들기

이 절에서는 프로젝트를 만들어 이름을 지정한 다음 프로젝트에 클래스를 추가합니다. 이 클래스는 컨트롤 배열을 구현하는 코드를 캡슐화합니다.

ButtonArrayProject 및 ButtonArray 구성 요소를 만드는 방법

  1. 파일 메뉴에서 새로 만들기를 가리킨 다음 프로젝트를 선택하여 새 프로젝트 대화 상자를 엽니다.
  2. Visual Basic 또는 Visual C# 프로젝트 목록에서 Windows 응용 프로그램 프로젝트 템플릿을 선택하고 이름 상자에 ButtonArrayProject를 입력합니다.
  3. 파일 메뉴에서 모두 저장을 선택하여 프로젝트를 저장합니다.

컬렉션 구현

앞에서 만든 ButtonArray 클래스는 컬렉션 구현을 통해 컨트롤 배열을 보관하고 구성하는 작업을 처리합니다. 컬렉션이란 인덱싱된 개체 변수 목록과 컬렉션의 개체를 추가, 제거 또는 조작하는 메서드를 포함하는 개체입니다. 이 절에서는 컬렉션에 필요한 대부분의 기능을 제공하는 .NET Framework 클래스인 System.Collections.CollectionBase에서 상속하는 클래스와 필요한 기능을 제공할 구현 메서드를 만듭니다.

상속된 클래스를 만드는 방법

  1. 프로젝트 메뉴에서 클래스 추가를 선택합니다.
  2. 클래스 이름을 ButtonArray.vbButtonArray.cs로 적절하게 지정합니다.

    클래스를 위한 코드 편집기가 열립니다.

  3. 클래스 선언에 클래스가 .NET Framework System.Collections.CollectionBase 클래스에서 상속된다고 지정합니다.
    ' Visual Basic
    Public Class ButtonArray
       Inherits System.Collections.CollectionBase
    End Class
    
    // C#
    public class ButtonArray : System.Collections.CollectionBase
    {
       // 디자이너에서 추가하는 코드 생략 
    }

System.Collections.CollectionBase 클래스는 컬렉션에 필요한 기능을 대부분 제공합니다. 여기에는 컬렉션에서 포함하는 개체를 추적하는 List 개체, 현재 컬렉션에 있는 개체의 전체 개수를 관리하는 Count 속성 및 특정 인덱스의 개체를 제거할 수 있도록 하는 RemoveAt 메서드 등이 포함됩니다. 컨트롤 배열 컬렉션을 구현할 때 이러한 각 기능을 사용합니다.

각 컨트롤 배열 구성 요소는 단일 폼과 연결되므로 필드를 추가하여 해당 폼에 대한 참조를 보관해야 합니다. 참조를 보관할 읽기 전용 private 필드를 만들려면 각 컨트롤 배열 구성 요소를 하나의 폼에만 연결해야 합니다.

구성 요소에 읽기 전용 private 필드를 추가하는 방법

  • 클래스 선언 안에 다음 줄을 추가합니다.
    ' Visual Basic
    Private ReadOnly HostForm as System.Windows.Forms.Form
    
    // C#
    private readonly System.Windows.Forms.Form HostForm;

컬렉션에 구현해야 할 첫째 메서드는 AddNewButton입니다. 이 메서드는 새 단추 컨트롤을 만들어 원하는 폼에 추가합니다. 또한 이 메서드를 사용하여 새 단추의 초기 속성도 설정합니다.

AddNewButton 메서드를 구현하는 방법

  • ButtonArray 클래스의 코드 편집기에서 다음 코드를 입력합니다.
    Public Sub AddNewButton()
       ' Button 클래스의 새 인스턴스를 만듭니다. 
       Dim aButton As New System.Windows.Forms.Button()
       ' 컬렉션의 내부 목록에 단추를 추가합니다. 
       Me.List.Add(aButton)
       ' HostForm 필드에서 참조하는 폼의 컨트롤 컬렉션에  
       ' 단추를 추가합니다. 
       HostForm.Controls.Add(aButton)
       ' 단추 개체의 초기 속성을 설정합니다.
       aButton.Top = Count * 25
       aButton.Left = 100
       aButton.Tag = Me.Count
       aButton.Text = "단추 " & Me.Count.ToString
    End Sub
    
    // C# 
    public void AddNewButton()
    {
       // Button 클래스의 새 인스턴스를 만듭니다. 
        System.Windows.Forms.Button aButton = new 
          System.Windows.Forms.Button();
       // 컬렉션의 내부 목록에 단추를 추가합니다. 
       this.List.Add(aButton);
       // HostForm 필드에서 참조하는 폼의 컨트롤 컬렉션에 
       // 단추를 추가합니다. 
       HostForm.Controls.Add(aButton);
       // 단추 개체의 초기 속성을 설정합니다. 
       aButton.Top = Count * 25;
       aButton.Left = 100;
       aButton.Tag = this.Count;
       aButton.Text = "단추 " + this.Count.ToString();
    }

이 메서드는 다음을 수행합니다.

  1. 새 단추를 만듭니다.
  2. 내부 목록과 HostForm에서 참조하는 폼의 컨트롤 컬렉션에 새 단추를 추가합니다.
  3. 단추의 인덱스에 Tag 속성을 설정하는 것을 비롯하여 초기 속성을 설정합니다. 이 절에서 컨트롤의 추가 속성을 설정하기 위한 코드를 추가합니다.

또한 HostForm 필드의 값을 설정하고 컨트롤 배열 클래스의 새 인스턴스가 만들어질 때마다 폼에 새 단추를 자동으로 추가하는 생성자(구성 요소를 인스턴스화할 때 실행되는 메서드)도 만들어야 합니다. 다음과 같은 방법으로 생성자를 만들 수 있습니다.

생성자를 만드는 방법

  • 클래스의 생성자를 만듭니다.
    ' Visual Basic
    Public Sub New(ByVal host as System.Windows.Forms.Form)
       HostForm = host
       Me.AddNewButton()
    End Sub
    
    // C# 
    // 기본 생성자를 다음 생성자로 바꿉니다. 
    public ButtonArray(System.Windows.Forms.Form host)
    {
       HostForm = host;
       this.AddNewButton();
    }

    생성자에는 단추 배열을 놓을 폼을 매개 변수로 사용해야 합니다. 생성자는 HostForm 필드에 제공된 값을 할당한 다음 클래스의 AddNewButton 메서드를 호출하여 폼에 새 단추를 추가합니다.

컨트롤 배열 노출

배열에 컨트롤을 만들고 추적할 수 있는 방법을 구현했으므로 컨트롤이 다른 개발자에게 노출될 수 있도록 해야 합니다. 속성을 사용하여 이렇게 할 수 있습니다. 인덱스를 기반으로 특정 단추에 대한 참조를 반환하는 기본 속성(Visual Basic)이나 인덱서(C#)를 만듭니다. 이렇게 하면 컨트롤 배열에 일반적인 MyButtonArray(myIndex) 구문을 프로그래밍으로 사용할 수 있습니다.

기본 속성을 만드는 방법

  • 구성 요소에 다음 코드를 추가합니다.
    ' Visual Basic
    Default Public ReadOnly Property Item(ByVal Index As Integer) As _
       System.Windows.Forms.Button
       Get
          Return CType(Me.List.Item(Index), System.Windows.Forms.Button)
       End Get
    End Property
    
    // C#
    public System.Windows.Forms.Button this [int Index]
    {
    get
       {
          return (System.Windows.Forms.Button) this.List[Index];
       }
    }

Remove 메서드 구현

배열의 단추를 노출시키기 위한 속성을 만들었으므로 배열에서 단추를 제거하는 메커니즘을 구현할 수 있습니다. 배열에서 단추를 제거하려면 컬렉션의 내부 List 개체와 폼의 Controls 컬렉션에서 단추를 제거해야 합니다.

Remove 메서드를 구현하는 방법

  • 구성 요소에 다음 메서드를 추가합니다.
    ' Visual Basic
    Public Sub Remove()
       ' 제거할 단추가 있는지 확인하십시오.
       If Me.Count > 0 Then
          ' 배열에 추가된 마지막 단추를 호스트 폼의 컨트롤 컬렉션에서 
          ' 제거합니다. 배열을 액세스할 때 기본 속성을  
          ' 사용합니다. 
          HostForm.Controls.Remove(Me(Me.Count -1))
          Me.List.RemoveAt(Me.Count -1)
       End If
    End Sub
    
    // C#
    public void Remove()
    }
       // 제거할 단추가 있는지 확인합니다. 
       if (this.Count > 0)
       {
          // 배열에 추가된 마지막 단추를 호스트 폼의 컨트롤 컬렉션에서 
          // 제거합니다. 배열을 액세스할 때 인덱서를 
          // 사용합니다. 
          HostForm.Controls.Remove(this[this.Count -1]);
          this.List.RemoveAt(this.Count -1);
       }
    }

공통 이벤트 처리기 만들기

마지막 단계에서는 배열의 공통 이벤트를 처리할 이벤트 처리기를 만듭니다. 이 데모에서는 단추의 클릭 이벤트를 처리할 메서드를 만든 다음 이벤트를 이벤트 처리기와 연결하기 위한 코드를 추가합니다.

공통 이벤트 처리기를 만드는 방법

  • 구성 요소에 다음 메서드를 추가합니다.
    ' Visual Basic
    Public Sub ClickHandler(ByVal sender As Object, ByVal e As _
       System.EventArgs)
       MessageBox.Show("단추를 클릭했습니다. " & CType(CType(sender, _
          Button).Tag, String))
    End Sub
    
    // C#
    public void ClickHandler(Object sender, System.EventArgs e)
    {
       System.Windows.Forms.MessageBox.Show("단추를 클릭했습니다. " + 
          ((System.Windows.Forms.Button) sender).Tag);
    }

    이 메서드는 단추의 Tag 속성에 저장된 인덱스를 검색하여 어떤 단추를 클릭했는지를 나타내는 메시지 상자를 표시합니다. 이벤트 처리기에서와 마찬가지로 이 메서드의 서명은 처리할 이벤트의 서명과 같아야 합니다.

또한 이벤트를 이벤트 처리기와 연결해야 합니다.

이벤트를 이벤트 처리기와 연결하는 방법

  • 다음 코드를 AddNewButton 메서드에 추가합니다.
    ' Visual Basic
    AddHandler aButton.Click, AddressOf ClickHandler
    
    // C#
    aButton.Click += new System.EventHandler(ClickHandler);

프로젝트 테스트

프로젝트가 완성되었으므로 구성 요소의 기능을 테스트하는 응용 프로그램을 만듭니다.

테스트 응용 프로그램을 만드는 방법

  1. 솔루션 탐색기에서 Form1을 마우스 오른쪽 단추로 클릭하고 바로 가기 메뉴에서 디자이너 보기를 선택합니다.

    Form1의 디자이너가 열립니다.

  2. 도구 상자에서 폼에 단추 두 개를 추가합니다.
  3. 이 단추들을 폼의 오른쪽에 다시 배치합니다.
  4. 단추의 속성을 다음과 같이 설정합니다.
    단추이름텍스트
    Button1btnAdd단추 추가
    Button2btnRemove단추 제거
  5. 솔루션 탐색기에서 Form1을 마우스 오른쪽 단추로 클릭하고 바로 가기 메뉴에서 코드 보기를 선택합니다.

    Form1의 코드 편집기가 열립니다.

  6. Form1의 클래스 선언 내에 컨트롤 배열 개체를 선언합니다.
    ' Visual Basic
    ' 새 ButtonArray 개체를 선언합니다.
    Dim MyControlArray as ButtonArray
    
    // C#
    // 새 ButtonArray 개체를 선언합니다.
    ButtonArray MyControlArray;
  7. 메서드가 끝나기 바로 전에 있는 폼의 생성자에 다음 코드를 추가합니다.
    ' Visual Basic
    MyControlArray = New ButtonArray(Me)
    
    // C#
    MyControlArray = new ButtonArray(this);

    이 명령문은 새 ButtonArray 개체를 만듭니다. 매개 변수(Me 또는 this)는 새 ButtonArray를 만들 폼을 참조하고 이 폼에 단추 배열이 놓입니다.

  8. 솔루션 탐색기에서 Form1을 마우스 오른쪽 단추로 클릭하고 바로 가기 메뉴에서 디자이너 보기를 선택합니다.
  9. 디자이너에서 btnAdd를 두 번 클릭하여 btnAdd_Click 이벤트의 코드 편집기를 엽니다.
  10. 다음과 같이 btnAdd_Click 메서드에서 MyControlArrayAddNewButton 메서드를 호출하기 위한 코드를 추가합니다.
    ' Visual Basic
    ' MyControlArray의 AddNewButton 메서드를 호출합니다. 
    MyControlArray.AddNewButton()
    ' Button 0의 BackColor 속성을 변경합니다.  
    MyControlArray(0).BackColor = System.Drawing.Color.Red
    
    // C#
    // MyControlArray의 AddNewButton 메서드를 호출합니다. 
    MyControlArray.AddNewButton();
    // Button 0의 BackColor 속성을 변경합니다. 
    MyControlArray[0].BackColor = System.Drawing.Color.Red;
  11. 솔루션 탐색기에서 Form1을 마우스 오른쪽 단추로 클릭하고 바로 가기 메뉴에서 디자이너 보기를 선택합니다.
  12. 디자이너에서 btnRemove를 두 번 클릭하여 btnRemove_Click 이벤트의 코드 편집기를 엽니다.
  13. btnRemove_Click 메서드에서 다음 코드를 추가합니다.
    ' Visual Basic
    ' MyControlArray의 Remove 메서드를 호출합니다. 
    MyControlArray.Remove()
    
    // C#
    // MyControlArray의 Remove 메서드를 호출합니다. 
    MyControlArray.Remove();
  14. 프로젝트를 저장합니다.

프로젝트를 테스트하는 방법

  1. 디버그 메뉴에서 시작을 선택합니다.

    단추 추가, 단추 제거, Button 1이라는 세 개의 단추가 있는 Form1이 열립니다.

  2. Button 1을 클릭합니다.

    메시지 상자가 표시되고 이 메시지 상자에 인덱스가 올바르게 표시됩니다.

  3. 단추 추가 단추를 몇 번 클릭합니다.

    클릭할 때마다 폼에 새 단추가 추가됩니다. 새로 추가된 각 단추를 클릭하면 단추의 인덱스를 올바르게 보고하는 메시지 상자가 표시됩니다. 또한 btnAdd_Click 이벤트에 있는 다음 줄 때문에 Button 0의 색이 빨강으로 변경되었습니다.

    MyControlArray(0).BackColor = System.Drawing.Color.Red
  4. 단추 제거 단추를 몇 번 클릭합니다.

    클릭할 때마다 폼에서 단추가 제거됩니다.

  5. 폼 왼쪽에 있는 모든 단추가 제거될 때까지 이 단추를 클릭합니다.
  6. 단추 추가 단추를 다시 클릭합니다.

    폼에 단추가 다시 추가되고 올바른 인덱스 번호가 매겨집니다.

결론

이 기사에서는 컨트롤 배열의 기능을 캡슐화하는 구성 요소를 만드는 방법을 보여 주었습니다. 폼에서 컨트롤을 동적으로 추가 및 제거하는 메서드를 만드는 방법과 기본 속성이나 인덱서를 통해 개체를 노출시키는 방법에 대해 살펴 보았습니다. 모든 기능을 구현했으므로 구성 요소에 맞는 코드를 작성하여 컨트롤 배열을 확장할 수 있습니다.