2011. 9. 9. 12:32

C++에 함수 콜백이 있다면 C#에는 이벤트가 있죠.
이벤트라는 것은 특정 행위가 일어났을 때 이것을 외부로 알리기 위한 도구입니다.

 

 

0. 이벤트 사용

설마 이 글을 읽으면서 아직도 이벤트 연결을 못 하는 사람이 있을 거라는 생각은 하지 않지만....그래도 모르니 ㅎㅎㅎ

 

//이벤트 연결
this.insSkype.OpenCompleteEvent += new claSkype.OpenCompleteEventHandler(insSkype_OpenCompleteEvent);

...
...

void insSkype_OpenCompleteEvent(object sender, claSkype.OpenCompleteEventArgs e)
{
    MessageBox.Show(e.Temp.ToString());
}

 

 

+=을 하는 순간 자동생성할 건지 물어봅니다.
여기서 탭키를 누르면 이벤트가 자동으로 생성됩니다.

 

 

1. 일반적인 이벤트 형태

일반적으로 사용되는 이벤트들(클릭이나 온로드 같은...)의 형태로 선언하는 방법입니다.

#region 오픈 이벤트가 완료되면 발생 합니다. 발생하는 이벤트
	
    /// <summary>
    /// 이벤트 발생시 전달할 모델
    /// </summary>
    public class OpenCompleteEventArgs : EventArgs
    {
        public int Temp = 0;
        public OpenCompleteEventArgs(int Temp)
        {
            this.Temp = Temp;
        }
    }
    
    public delegate void OpenCompleteEventHandler(object sender, OpenCompleteEventArgs e);
 
    /// <summary>
    /// 오픈 이벤트가 오면 발생합니다.
    /// </summary>
    public event OpenCompleteEventHandler OpenCompleteEvent;
 
    protected void OnOpenComplete(OpenCompleteEventArgs e)
    {
        if (OpenCompleteEvent != null)
        {
            OpenCompleteEvent(this, e);
        }
    }
 
    /// <summary>
    /// 오픈 완료 이벤트
    /// </summary>
    private void OpenComplete(int Temp)
    {
        OpenCompleteEventArgs e = new OpenCompleteEventArgs(Temp);
        OnOpenComplete(e);
    }
#endregion

 

6번 줄 : 이벤트 발생 시 전달용으로 사용할 모델

 

15번 줄 : 이벤트에 사용할 대리자(델리게이트, delegate)를 생성합니다.

 - 이때 매개변수로 전달하는 'OpenCompleteEventArgs'는 전달하고자 하는 모델입니다.

 - 원하는 매개변수로 설정합니다.

 

20번 줄 : 생성한 대리자를 이용하여 이벤트를 선언합니다.

 

22번 줄 : 이 이벤트를 발생시킬 때 사용할 메서드

 - 외부에서 연결된 이벤트가 없는 경우 에러가 나므로 'null'일 때는 이벤트가 발생하지 않도록 합니다.

 

33번 줄 : 이벤트를 발생시키는 테스트 코드

 

 

'OpenCompleteEventArgs'는 'EventArgs'를 상속받아 일반적인 이벤트 형태이기 때문에 매개변수를 지정할 수 있습니다.

해당 매개를 지정하여 필요한 정보를 넘기고 쓰는 쪽에서는 'e.' 값으로 사용할 수 있습니다.

'OpenComplete'은 이벤트 발생을 공통화시키기 위해 사용하는 함수로 일반 코드에서 동일하게 코딩하면 동일하게 동작합니다.

 

 

2. 간소화된 방법

위코드는 복잡합니다.
이벤트를 발생시킨 클래스의 정보가 필요 없다면 더더욱 복잡하죠 ㅎㅎㅎ

이럴 때 사용하는 것이  간소화 방법입니다.

public delegate void ReloadPageDelegate(int Temp);
public event ReloadPageDelegate OnReloadPage;
 
private void ReloadPage(int Temp) 
{ 
	if(null != OnReloadPage)
    {
    	OnReloadPage(Temp);
    }
}

 

전달용 모델은 따로 선언하지 않고,

사용할 대리자를 선언할 때 매개변수만 지정합니다.

 

'ReloadPage'를 호출하면 동일하게 동작하는 것을 확인할 수 있습니다.

 

 

3. 간소화된 표준 방법

간단하게 이벤트를 구현하면서도 표준이벤트를 이용하여 구성하는 방법입니다.

/// <SUMMARY>
/// 클릭 이벤트
/// </SUMMARY>
public event EventHandler OnClick;
 
public void ButtonClick(object sender, EventArgs args)
{
    if (OnClick != null)
    {
        OnClick(this, args);
    }
}

 

'EventHandler'는 표준 이벤트 대리자입니다.

이것을 이용하면 별도의 대리자를 선언하지 않아도 됩니다.

'ButtonClick'를 호출하면 원하는 동작을 합니다.

 

 

마무리

그때그때 상황에 맞는 걸 쓰시면 되겠습니다.

 

저는 거의 '2. 간소화된 방법'을 사용합니다.

커스텀 데이터를 전달해야 하는 일이 많으니까요 ㅎㅎㅎ