DONE_IS_BETTER_THAN_PERFECT.

C# 관련 프로그래밍

Etc
2007. 9. 24. 19:23
C#, VB.Net, Java 간의 비교 9 ▒ 프로그래밍

2004/10/08 02:34

http://blog.naver.com/sunmanddang/6380424

===================================================================
9장)
===================================================================

앞서 폰트의 색상 설정 기준
    blue: 코드, green: 주석, bold: 강조, red: 더 강조, gray: 인용 ...

여기서도 이전 장과 마찬가지로 VB.NET과 C#에 대해서만 다룰 것이다.
Java에서의 이벤트 모델은 본인의 짧은 지식으로는 설명할 능력이 안되기 때문이다.

-----------------------------
이벤트
-----------------------------
이벤트란 무엇인가?
이벤트에 대한 정의는 MSDN에 여러가지 형태로 어찌보면 서로 다른 의미같이 애매모호한 형태로 설명하고 있지만
실제로는 모두 동일한 이야기를 하고 있는 것이다.
만일 확실히 이벤트를 이해하기 위해서는 이벤트 큐(event queue), 후킹(hooking) 과 콜백(callback)등의 개념이 필요하다.

다음은 MSDN에서 말하는 이벤트에 대한 설명이다.

이전에는 구성 요소에서 비동기 "이벤트"에 대한 정보를 해당 클라이언트에 전달하는 방법이 프로그래밍 환경에 따라 모두 달랐습니다.
C 언어에는 이 목적에 맞는 함수 콜백이 있지만 C++에는 개체 메서드에 대한 이런 종류의 콜백이 부족합니다.
따라서 C++에는 창 메시지, 이벤트 인터페이스, 하드 코딩된 콜백 메서드 이름, 썽크 등을 사용하여 이 문제를 해결하는 데 많은 시간이 필요하게 됩니다.
COM에서는 이벤트 모델이 정의되지만 구현과 유지 관리에 많은 시간이 걸리고 두 개의 Native C++ 개체 간에는 이벤트가 지원되지 않습니다.
           -- MSDN 에서..

.NET Framework에서의 이벤트는 대리자 모델에 기반합니다.
개체 지향 프로그래밍에서의 디자인 패턴에 익숙한 사용자는 이것이 옵서버 디자인 패턴임을 짐작할 수 있을 것입니다.
이 단원에서는 대리자 모델, 응용 프로그램에서 이벤트를 사용하는 방법, 클래스에서 이벤트를 발생시키는 방법 등에 대해 설명합니다.
           -- MSDN 에서..

이벤트는 동작의 발생을 알리기 위해 개체에서 보내는 메시지입니다.
이 동작은 마우스 클릭과 같은 사용자 상호 작용으로 일어나거나 다른 프로그램 논리에 의해 트리거될 수 있습니다.
이벤트를 발생시키는(트리거하는) 개체를 이벤트 송신기라고 하며 이벤트를 캡처하고 이벤트에 응답하는 개체를 이벤트 수신기라고 합니다.
이벤트 통신에서, 이벤트 송신기 클래스는 해당 클래스에서 발생되는 이벤트를 어느 개체 또는 메서드에서 수신(처리)하는지 모릅니다.
이러한 이유로 소스와 수신기 사이에 매개체(포인터와 같은 메커니즘)가 필요합니다.
.NET Framework에서는 함수 포인터의 기능을 제공하는 특수 형식(Delegate)을 제공합니다.
대리자는 메서드에 대한 참조를 가질 수 있는 클래스입니다.
하지만 다른 클래스와는 달리, 대리자 클래스에는 서명이 있어 서명과 일치하는 메서드에 대한 참조만을 유지합니다.
            -- MSDN 에서..


이외에도 이벤트에 대한 정보는 여러 군데서 나타나는데 이들 내용을 종합해 결론을 내리면 다음과 같다.
이벤트란 오브젝트 내에서 중요한 사항(물론 중요하지 않을 수도 있겠지만 오브젝트 입장에서는 상당히 중요함..)이 발생했다는 것을
어플리케이션에게 알려주기 위한 신호이다.
폼 위에서 버튼을 클릭했다면 이벤트는 버튼에서 발생하기 때문에 버튼을 이벤트 송신기 또는 이벤트 소스라고 부르며
이벤트에 에 반응해야 할 폼을 이벤트 수신기 또는 이벤트 리스너라 부른다.
(이벤트 수신기는 꼭 폼이 아니어도 되며 어떤 오브젝트든지 가능하다. 하지만 여기서는 일반적으로 폼 위에 버튼이 있으므로 폼을 수신기라고 했을 뿐이다.)
하지만 버튼이 눌렸을 때 어느 개체(여기서는 폼이 될 것이다)의 어떤 메서드(혹은 함수)에서 처리해야 할지 알지 못하기 때문에 송신기와 수신기 사이에
매개체가 필요하다는 것이다. 닷넷에서는 이를 위해 함수 포인터의 기능을 하는 델리깃(delegate)을 제공한다는 것이다.
또한 이벤트 함수의 구현은 반환 값이 함수(VB.NET에서는 Sub 프로시져)로 구현되어야 하며 이 함수 내에 이벤트가 발생했을 때 처리해야 할 코드를
개발자가 입력해주면 된다.
이러한 Delegate를 사용해야 하는 이벤트 방식은 전적으로 닷넷에 해당하는 내용이다. unmanaged C++ 과 같은 프로그래밍 언어에서는
콜백(Callback), 후킹(Hooking) 등의 방법으로 이벤트가 구현하는데 콜백이라는 자체가 델리깃과 유사한 함수 포인터 사용을 의미하기 때문에
결론적으로는 서로 유사한 방식으로 이벤트가 구현되는 것이라 할 수 있다. 자바도 이와 유사한 방식을 취하고 있다.

하지만 이 내용들이 전혀 이해가 안되는 사람들은 다 접어 두고 결론적으로 다음과 같이 이해하면 된다.
이벤트는 사용자나 시스템에 의해서 자동으로 발생하게 되며 처리할 이벤트 함수는 반환 값이 없는 함수(VB.NET에서는 Sub 프로시저)로 구현된다는 것이다.
이렇게만 알아두자.

자 다음은 이벤트 관련 용어에 대해서 알아보자.

1.이벤트의 선언 : 이벤트는 클래스, 구조체, 모듈 및 인터페이스 내에 선언된다.
------------------
VB.NET의 경우
------------------
    Public Event 이벤트이름([매개변수리스트])        '//단순하게 이벤트를 선언하고 매개변수를 선언한다.
    '//참고: 이벤트의 매개변수는 이벤트 매개변수의 표준안을 따르도록 권장하고 있다. 이에 대해서도 다시 다룰 것이다.
    또는 C#과 동일하게 사용할 수 있다.
    Public Delegate sub 델리깃이름([매개변수리스트])      '// 사용할 프로젝트의 선언부에서
    Public Event 이벤트이름 As 델리깃이름                '// 클래스 내의 선언부에서
------------------
C#의 경우
------------------
    public delegate void 델리깃이름([매개변수리스트]);  // 사용할 프로젝트의 선언부에서
    public event 델리깃이름 이벤트이름;                    // 클래스 내의 선언부에서
    //참고 : event 키워드를 사용하면 코드에서 일부 "이벤트"가 발생할 때 호출될 대리자를 지정할 수 있습니다.
    //대리자는 코드가 이벤트 발생을 알릴 때 호출되는 관련 메서드를 하나 이상 포함할 수 있습니다.
    //또한 한 프로그램의 이벤트를 .NET Framework 공용 언어 런타임을 대상으로 하는 다른 프로그램에서 사용할 수 있게 만들 수 있습니다. -- MSDN

------------------

2.이벤트 발생 : 이벤트는 특정 동작이 발생했음을 알리는 메시지이며 이러한 메시지를 브로드캐스트하는 동작을 이벤트를 발생시킨다라고 말한다.
------------------
VB.NET의 경우
------------------
    RaiseEvent 이벤트이름(매개변수값리스트)    '//이벤트를 발생시키고자 하는 프로시저 내에서
    '//참고: 이벤트는 선언된 범위 내에서 발생해야 하며 상속받은 클래스에서 상속해준 클래스의 이벤트를 호출할 수 없다.
------------------
C#의 경우
------------------
   public void 델리깃으로사용할메서드([매개변수리스트]) { //꼭 public일 필요는 없다. public이 아니어도 되는 경우는 같은 프로젝트일 경우다.
           //호출될 이벤트의 이름과 매개변수 값을 적는다.
           이벤트이름([매개변수값리스트]);
   }
------------------

3.이벤트 송신기 : 이벤트를 발생시킬 수 있는 개체를 이벤트 송신기 또는 이벤트 소스라고 부른다. 이벤트 송신기의 예로는 폼, 컨트롤 등이 있다.

4.이벤트 처리기 : 이벤트 처리기는 해당되는 이벤트가 발생할 때 호출되는 반환값이 없는 함수(이벤트 소스에 값을 반환할 수 없기 때문이다)이다.

------------------
VB.NET의 경우
------------------
    Private Sub 이벤트처리기로사용할프로시저([매개변수리스트])
   
    End Sub
------------------
C#의 경우
------------------
   private void 이벤트처리기로사용할프로시저([매개변수리스트]) {
  
   }
------------------

5.이벤트와 이벤트 처리기 연결 : 이벤트 소스에서 이벤트가 발생되면 처리될 이벤트 처리기의 함수와 연결을 한다. 즉, 위임을 한다.
------------------
VB.NET의 경우
------------------
    //연결할 이벤트 프로시저의 이름 뒤에 Handles 구문을 사용할 수 있다.
    //이것은 디자인 타임시에만 사용가능한 구문이다.
    Private Sub 이벤트처리기로사용할프로시저([매개변수리스트]) Handles 이벤트소스오브젝트.이벤트
   
    End Sub
    '//이와 같이 Handles를 사용하면 WithEvents 문을 사용하여야만 이벤트 처리를 할 수 있다.
또는 다음과 같이 동적으로 런타임 시에 연결을 할 수 있다.
    AddHandler 이벤트이름, AddressOf 이벤트처리기로사용할프로시저 '// 핸들러 추가.
------------------
C#의 경우
------------------
    이벤트이름 += new 델리깃이름(이벤트처리기로사용할프로시저) ; //+= new 델리깃이름() 은 VB.NET에서의 AddHandler와 동일하다.
------------------
C#에서는 += new 델리깃이름()이 VB.NET에서는 AddHandler 이며 C#에서의 -= new 델리깃이름() 은 VB.NET에서의 RemoveHandler와 동일하다.
C#과 VB.NET에서의 이벤트 처리 방식은 거의 동일하지만 약간의 차이가 있다. 이에 대해서는 설명하지 않을 것이므로 무엇이 차이가 있는지는
여러분들이 직접 도움말을 찾아서 연구해보자.

자 이제 무지하게 복잡해졌다.
무슨 넘의 이벤트 하나 쓰는데 이렇게 복잡하나. 그냥 써도 되던데...
좋은 약이 그냥 먹어도 좋지만 알고 먹으면 더 좋은 것처럼 이벤트도 그렇다고 생각하자.

다음은 이러한 이벤트를 우리가 정의하기 전에 이미 이벤트가 정의되어 있는 폼이나 컨트롤에서의 이벤트가 어떻게 처리되는지에 대해서 알아볼 것이다.

-----------------------------
이미 정의된 이벤트
-----------------------------
이벤트를 여러분들이 정의해서 사용할 수도 있지만 이미 이벤트를 가지고 있는 클래스를 사용할 수도 있다.
여러분들이 닷넷을 실행시켜 C#이나 VB.NET 어떤 언어로든 프로그램을 작성하게 되면 최소한 하나 이상의 폼 오브젝트와 컨트롤을 사용하게 된다.
그리고 폼과 컨트롤을 사용할 때 폼이나 컨트롤에 이미 정의 되어 있는 이벤트 내에서 프로그램을 작성하게 된다.
이미 정의 되어 있는 이벤트들의 종류는 각 폼이나 컨트롤의 용도에 따라서 서로 다른데 대부분 실행시에 사용자에게 보일 수 있는 컨트롤들은
Click, DblClick, MouseMove, MouseDown 등 공통적인 이름으로 미리 정의된 이벤트들을 가지고 있다.
클래스를 새로 만들 때 이벤트의 이름들은 여러분들의 마음대로 정의할 수 있지만 표준안이라는 것이 있어 이벤트를 만들 때
"용어는 이렇게 저렇게 해라 매개변수는 또 이렇게 저렇게 해라" 등의 표준안이라는 규칙을 제공한다.
따라서 아무리 새로운 컨트롤을 사용한다고 하더라도 마우스 왼쪽 버튼을 누르면 "음~ Click 이라는 이벤트가 발생하겠지?" 라고 추측할 수 있는 것이다.
하지만 여러분들이 만든 컨트롤에서 마우스가 눌렸을 때 Click이라고 사용하지 않고 MouseClick , Down, Opps, Ohmygod 등의 원하는 이름으로
얼마든지 정의할 수 있지만 그렇게 하면 컨트롤은 사용하기 어렵다는 이유로 시장에서 사장되기 딱 좋은 케이스가 될 것이다.
( 참고로 컨트롤에 공통적으로 사용되는 이벤트를 정의할 때는 어떻게 해라~라는 표준안도 MSDN에 나와 있으니 참고하길 바란다.)

이제 폼 위에 올려 놓은 버튼을 클릭하면 어떻게 Button1_Click이라는 이벤트 프로시저가 동작되는지에 대해서 자세히 살펴볼 것이다.
------------------
VB.NET의 경우
------------------
    1.폼위에 버튼을 올려 놓으면(코드로 직접 작성가능) 먼저 선언부에 버튼변수가 WithEvents 예약어와 함께 선언된다.
      이 키워드는 버튼을 사용할 때 이벤트까지 함께 사용하겠다는 것을 의미한다.
      WithEvents 예약어를 제거하면 버튼이 가지고 있는 어떠한 이벤트도 발생하지 않는다.

        Friend WithEvents Button1 As System.Windows.Forms.Button

     그리고 이어서 폼(컨테이너)에 버튼이 보이도록 다음과 같은 코드가 자동으로 생성된다. 다음 코드들이 없으면 폼 위에 버튼이 보이지 않는다.

        Me.Button1 = New System.Windows.Forms.Button()
        Me.Button1.Location = New System.Drawing.Point(104, 104)
        Me.Button1.Name = "Button1"
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Button1"
        Me.Controls.AddRange(New System.Windows.Forms.Control() {Me.Button1})
   
    2. 이제 (디자인 화면에서) 여러분들이 버튼을 더블클릭하면 다음과 같이 디폴드 이벤트인 버튼의 클릭 이벤트 프로시저가 생긴다.
    여기서 주의 깊게 보아야 할 것은 이벤트 프로시저의 맨 마지막에 있는 Handles Button1.Click 구문이다.
    Handles 구문은 뒤에 오는 버튼의 클릭 이벤트와 앞에 선언된 Button1_Click 이라는 함수(이벤트 처리기라고 불렀었다)와 서로 연결을 시킨다.

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       
    End Sub
   

    이벤트 처리기는 어떤 것이든지 상관없다. Button1_Click 을 Button1Down이나 btnClick 또는 한글로 "버튼이눌렸음" 으로 변경해도 된다.
    여기서 중요한 것은 이벤트처리기가 아니라 이벤트 처리기에서 사용된 매개변수가 중요한 것이다.
    Button 클래스에 정의된 이벤트 Click위 매개변수는 버튼 클래스에  ByVal sender As System.Object, ByVal e As System.EventArgs 의 구조로
    정의되어 있으며 이 이벤트가 발생(Raise 또는 Fire라는 용어를 사용)되면 Button1_Click 를 호출해달라고 요청하는 것이므로 서로가 매개변수는
    동일한 구조(유식한 말로 시그너쳐라고 부른다)를 가지고 있어야 한다.
   
    3. 또는 AddHandler를 사용하는 방법도 있다. 다음과 같이 "Button이눌려졌음"이라는 프로시져를 만든다. 매개변수는 Click 이벤트와 동일하게 한다.

    Private Sub Button이눌렸음(ByVal sender As System.Object, ByVal e As System.EventArgs)
        MessageBox.Show("눌려졌음")
    End Sub
   

    다음은 생성자의 InitializeComponent() 함수 아래쪽에 AddHandler 구문을 삽입한다.
    선언부의 Button1의 WithEvents 예약어는 지워도 상관없다.

    Public Sub New()
        MyBase.New()
        InitializeComponent()
        '//AddHandler는 다음과 같이 Button1의 Click 이벤트 하나에 대해서면 연결된다.
        '//컨트롤의 모든 이벤트를 사용하기 위해서는 WithEvents과 Handles 절을 사용한다.
        AddHandler Button1.Click, AddressOf Button이눌렸음
    End Sub

이제 실행한다음 Button1을 클릭해보자. 메시지 박스가 뜨는가?
즉, AddHandler를 사용하여 이벤트 처리기와 연결된 것이다.

------------------
C#의 경우
------------------
    1. C# 의 경우도 VB.NET과 크게 다를 바 없다.폼 위에 버튼을 올려 놓으면 다음과 같이 먼저 선언부에 사용할 버튼이 정의된다.
    이것이 바로 VB.NET과 다른 점인데 VB.NET에서는 WithEvents 예약어를 사용하여 일단 모든 이벤트를 다 사용할 준비를 하지만
    C#에서는 단지 버튼을 선언하기만 한다.
   
    private System.Windows.Forms.Button button1;

    그리고 이어서 VB.NET과 마찬가지로 폼(컨테이너)에 버튼이 보이도록 다음과 같은 코드가 자동으로 생성된다.
    다음 코드들이 없으면 폼 위에 버튼이 보이지 않는다.

    this.button1 = new System.Windows.Forms.Button();
    this.button1.Location = new System.Drawing.Point(80, 96);
    this.button1.Name = "button1";
    this.button1.TabIndex = 0;
    this.button1.Text = "button1";
    this.Controls.AddRange(new System.Windows.Forms.Control[] { this.button1});

    2. 이제 (디자인 화면에서) 버튼을 더블클릭하면 기본 이벤트인 버튼의 클릭 이벤트 void 형 함수가 생긴다.
    private void button1_Click(object sender, System.EventArgs e){
   
    }

    하지만 이것으로 어떻게 버튼이 눌렸는지 알 수 있을까.
    코드 상단부로 올라가보면 생성자에서 호출되는 InitializeComponent 함수를 보자.
    그러면 다음과 같은 한 줄이 추가되어 있음을 확인할 수 있다.
   
    this.button1.Click += new System.EventHandler(this.button1_Click);

    즉, 이 폼의 button1 오브젝트의 Click 이벤트는 이 폼에 있는 button1_Click 라는 이벤트 처리기와 연결을 시켜준다. 즉, 버튼의 클릭 이벤트가
    발생되면 자동으로 button1_Click 라는 함수를 호출하게 되는 것이다.
    만일 버튼이 가지고 있는 또 다른 이벤트를 처리하고 싶다면 버튼을 선택하고 속성창을 열어보면 상단에 번개 모양의 이벤트 표시가 있을 것이다.
    이 아이콘을 클릭하면 버튼에 정의되어 있는 모든 이벤트들이 표시될 것이다. 여기서 원하는 이벤트 이름을 더블클릭하면 표준안에 의거한
    네이밍 룰에 맞는 private void 버튼의이름_이벤트이름(매개변수) 의 이름으로 함수가 생긴다.
    그리고 또 다음과 같은 한 줄이 더 추가될 것이다.
   
    this.버튼이름.이벤트명 += new System.EventHandler(this.버튼의이름_이벤트명);

    여기서 자동으로 만들어지는 이름이 아닌 다른 이름을 사용할 수도 있다. 즉,위에서 버튼의이름_이벤트명 이 아니라 "클릭", "buttonClick" 등의
    원하는 이름을 얼마든지 사용할 수 있다.
   
자 C#과 VB.NET의 컨트롤 이벤트 처리 방식을 살펴보았다.
다른 점이 무엇인가?

C#에서는 단순히 컨트롤을 선언만 하면 되고 VB.NET에서는 WithEvents 라는 예약어를 사용해서 필요한 이벤트들은 Handles 절을 사용해서 언제든지
추가할 수 있도록 해놓은 것이다. (그림이 있어야 하는데..)

C#에서는 이벤트를 추가하기 위해서는 속성창의 이벤트 리스트에서 이벤트를 더블클릭하면 되고 VB.NET에서는 코드 창의 오브젝트리스트에서 원하는
컨트롤을 선택하고 왼쪽 이벤트 리스트 박스에서 원하는 이벤트를 선택하면 된다.(그림이 또 필요한데..)
(참고:VB.NET에서 코드 윈도우 상단의 오브젝트리스트박스에 컨트롤이 표시되는 이유는 WithEvents 구문때문이다.)
이때 C#의 경우에는 추가하는 이벤트마다 컨트롤.이벤트 += new System.EventHandler(실행할이벤트함수); 가 자동으로 생기며
VB.NET에서는 실행할 이벤트 프로시저 뒤에 Handles 컨트롤.이벤트 가 붙는다.
즉, C#의 경우에는 사용할 이벤트마다 이벤트 처리기를 추가하는 코드가 생성되지만 VB.NET은 Handles 절이 추가된다.
마지막으로 C#과 동일한 방식으로 구현하려면 WithEvents 예약어를 사용하지 않고 AddHandler를 사용하면 된다.

지금까지 설명한 내용은 정의되어 있는 이벤트를 닷넷이 어떻게 사용하는지에 대해서 설명했고
다음은 여러분들이 직접 이벤트를 정의하는 방법에 대해서 알아볼 것이다.

-----------------------------
새로운 이벤트의 정의
-----------------------------
사용자 정의 이벤트를 만들고 이를 사용하는 것은 대단히 간단하다.

------------------
VB.NET의 경우
------------------
    Public Class 이벤트를발생시킬클래스
        '//1. 이벤트의 선언: 다음과 같이 이벤트를 클래스나 모듈, 인터페이스 내에 선언한다
        '//   다음의 매개변수는 이벤트 정의 표준안에 따라 정의한 것이다.
        Public Event 발생할이벤트(ByVal sender As Object,ByVal e As EventArgs )
   
        [Public | Private ] [Sub | Function] 메서드명(매개변수 리스트) [ As 반환값타입 ]
            '//이벤트 파라미터 클래스 생성
            '//(여기서는 아무 데이타도 들어가 있지 않다. 사용자 정의 이벤트 파라미터 클래스를 생성하는 것이 좋다.)
            Dim e as New System.EventArgs()    
            '//2. 이벤트의 발생: 선언된 이벤트의 유효 범위 내에서 RaiseEvent 구문으로 이벤트를 발생시킬 수 있다.
              RaiseEvent 발생할이벤트(Me, e )
        End [Sub | Function]
       
    End Class

이제 위 클래스를 생성하여 이벤트를 테스트 해보는 테스트 클래스의 구조는 다음과 같다.
여기서는 WithEvents와 Handles을 사용한다.
    Public Class 테스트클래스
        '//선언부
        Private WithEvents 클래스변수명 As New 클래스명
       
        '//3. 이벤트의 사용: 해당 클래스에서 발생된 이벤트는 명명된 규칙에 의해 다음과 같이 작성한다.
        Private Sub 클래스변수명_발생할이벤트(ByVal sender As Object,ByVal e As EventArgs) Handle 이벤트를발생시킨클래스.발생할이벤트
       
        End Sub

또는 AddHandler 구문을 사용할 수도 있다.
       
        '//또는 선언부 내에서 다음과 같이 선언을 한다.
        Private  클래스변수명 As New 클래스명
       
        '//메서드 내에서 이벤트 핸들러를 추가한다.
        AddHandler 클래스변수명.발생할이벤트, AddressOf 클래스변수명발생할이벤트
       
        '//그리고 실제 이벤트가 발생했을 때 처리할 프로시저를 만든다.
        Private Sub 클래스변수명발생할이벤트(ByVal sender As Object,ByVal e As EventArgs)
       
        End Sub
    End Class

------------------
C#의 경우
------------------
    '//C#에서의 이벤트는 델리깃을 사용한다. 매개변수는 표준안을 따른다.
    public delegate void 델리깃(object sender ,System.EventArgs e);
   
    public class 이벤트를발생시킬클래스 {
        //이벤트의 선언 . 델리깃을 사용한다.
        public event 델리깃 나의이벤트;

        //다음 메서드가 호출되면 델리깃에게 이벤트를 위임한다.
        [private | public ] void 메서드명() {
            System.EventArgs e = new System.EventArgs() ;
            나의이벤트(this, e);
        }
    }

이제 위 클래스를 생성하여 이벤트를 테스트 해보는 테스트 클래스의 구조는 다음과 같다.
여기서는 델리깃을 사용하여 이벤트 처리기를 등록한다.

    public class 테스트클래스 {
       
        //선언문에서 변수를 선언한다.
        private eventClass objClass;
       
        //메서드나 생성자 컨트롤 초기화 함수에서 다음과 같이 사용할 클래스의 인스턴스를 만든다.
        objClass= new eventClass();
       
        //이벤트 핸들러에 이벤트처리기를 추가한다.
        this.objClass.나의이벤트 += new 델리깃(이벤트처리기) ;

        //이벤트가 발생했을 때 처리할 함수를 선언한다.
        private void 이벤트처리기(object sender,EventArgs e){
           
        }       
   
    }


그러나 실제 컨트롤의 이벤트를 보면 System.EventHandler를 사용하여 다음과 같이 선언되어 있다.
       
        this.컨트롤.이벤트 += new System.EventHandler(이벤트처리기);
       
그래서 나는 이렇게 하고 싶다. 어떻게 해야 하나?
--------------------
C#의 경우
--------------------
이벤트를 발생시킬 클래스에서 이번에는 EventHandler를 사용하는 예제를 보겠다.
여기서 EventHandler는 이벤트 데이터가 없는 이벤트를 처리할 메서드를 의미한다. 즉, 반드시 두번째 매개변수에는
System.EventArgs 가 와야 하며 만일 다른 이벤트 파라미터를 정의한다면 또 다른 종류의 이벤트 핸들러를 사용해야 한다.
즉, 없으면 만들어야 한다는 것이다.

그에 대해서는 다음 장에서 알아볼 것이다.
    public class 이벤트를발생시킬클래스
    {
        //이벤트 핸들러의 선언 : delegate와 유사
        private System.EventHandler 이벤트핸들러 ;
   
        //이벤트의 선언(이벤트의 발생에 대한 권한을 이벤트 핸들러에 위임한다)
        public event System.EventHandler 나의이벤트{
            add {
                이벤트핸들러 += value;
            }
            remove {
                이벤트핸들러 -= value;
            }
        }
        //다음 메서드가 호출되면 이벤트 핸들러가 이벤트를 가로챈다.
        [public | private ] void 메서드명() {
            System.EventArgs e = new System.EventArgs() ;
            이벤트핸들러(this,e );
        }
    }

이제 위 클래스를 생성하여 이벤트를 테스트 해보는 테스트 클래스의 구조는 다음과 같다.
이제 델리깃이 아닌 이벤트핸들러(개념은 델리깃과 동일)로 이벤트를 처리할 수 있다.

    public class 테스트클래스 {
       
        //선언문에서 변수를 선언한다.
        private eventClass objClass;
       
        //메서드나 생성자 컨트롤 초기화 함수에서 다음과 같이 사용할 클래스의 인스턴스를 만든다.
        objClass= new eventClass();
       
        //이벤트 핸들러에 이벤트처리기를 추가한다.
        this.objClass.나의이벤트 += new System.EventHandler(이벤트처리기) ;

        //이벤트가 발생했을 때 처리할 함수를 선언한다.
        private void 이벤트처리기(object sender,EventArgs e){
           
        }       
   
    }   


숙제
두 가지(이벤트 핸들러와 델리깃)를 사용하여 몇 가지의 이벤트를 만들어보고 만들어진 이벤트를 다른 클래스에서
호출하는 예제를 만들어라.
이벤트는 어떤 이름의 이벤트도 좋지만 위에서 말했던 이벤트의 매개변수에 대한 정의는 표준안을 따르도록 한다.
이벤트를 발생시키는 방법은 폼위에서 버튼을 클릭하면 이벤트가 있는 클래스의 이벤트를 발생시켜 폼에 있는
이벤트 프로시저(이벤트처리기)를 호출하여 이벤트가 호출되었음을 알려주면 된다.

--------------------
VB.NET의 경우
--------------------
물론 약간의 표현 방법이 다르지만 VB.NET의 경우에도 동일한 구조로 프로그래밍을 할 수 있다.
숙제
VB.NET을 모르는 사람은 쉽지 않을거라 생각하지만 그래도 해보는데 의의가 있다.


오늘은 여기까지...
다음은 이벤트의 매개변수인 EventArgs 클래스를 상속받아 사용자 정의 이벤트 매개변수 클래스를 만드는 방법에 대해서 알아볼 것이다.
이벤트의 매개변수는 일반적으로 그냥 임의대로 만들어도 되지만 위에서 사용했던 EventHandler의 경우처럼 이벤트 작성에 대한 표준안을
제공하기 때문에 우리들도 그 표준안을 따르는 것이 좋다.
그 표준안을 따라서 이벤트 매개변수 클래스에 대한 설명과 예제를 다룰 것이다.
역시 다음 장도 VB.NET과 C#에 대해서만 다룰 것이다.
java에 대해서는 내공이 많이 쌓이면 실을 예정이다.

이 글을 공유합시다

facebook twitter kakaoTalk kakaostory naver band
  • 글쓰기
  • 관리자
  • 카테고리
  • 맨위로