티스토리 뷰
실전 취소 가능한 버튼 컨트롤 만들기
Umc.Core.EventHandlerDictionary 클래스
이 클래스는 Umc.Core 프로젝트에 포함된 클래스 입니다. 이 클래스의 이름에서 알 수 있듯이 이벤트를 사전(Dictionary)로 관리하도록 하기 위한 클래스 입니다.
namespace Umc.Core
{
///<summary>
/// Umc.Core<br/>
/// Delegate 를담는 EventHandlerDictionary 컬렉션
///</summary>
public class EventHandlerDictionary : IDisposable
{
///<summary>
/// Umc.Core<br/>
/// Event 를담는컬렉션
///</summary>
private Dictionary<object,Delegate> eventDictionary = new Dictionary<object,Delegate>();
///<summary>
/// Umc.Core<br/>
/// EventHandlerDictionary 에 EventHandler 를추가한다.
///</summary>
///<param name="key">키값</param>
///<param name="value">Delegate</param>
public void AddHandler(object key, Delegate value)
{
if ( eventDictionary.ContainsKey(key) )
{
eventDictionary[key] = Delegate.Combine(eventDictionary[key], value);
}
else
{
eventDictionary[key] = value;
}
}
///<summary>
/// Umc.Core<br/>
/// EventHandlerDictionary 에 EventHandler 를제거한다.
///</summary>
///<param name="key">키값</param>
///<param name="value">Delegate</param>
public void RemoveHandler(object key, Delegate value)
{
if ( eventDictionary.ContainsKey(key) )
{
eventDictionary[key] = Delegate.Remove(eventDictionary[key], value);
}
}
public bool Contains(object key)
{
return this.eventDictionary.ContainsKey(key);
}
///<summary>
/// Umc.Core<br/>
/// EventHandlerDictionary 의인덱서
///</summary>
///<param name="key"></param>
///<returns></returns>
public Delegate this[object key]
{
get { return eventDictionary[key]; }
set { eventDictionary[key] = value; }
}
#region IDisposable 멤버
///<summary>
/// Umc.Core<br/>
/// EventHandlerDictionary 의자원을해제한다.
///</summary>
public void Dispose()
{
if( eventDictionary != null )
eventDictionary.Clear();
eventDictionary = null;
}
#endregion
}
} |
클래스 내부에는 Dictionary 제네릭 클래스의 오브젝트를 생성하여, AddHandler(), RemoveHandler() 를 통해 이벤트를 사전에 추가/삭제 하는 로직이 들어있습니다.
ButtonEx 네임스페이스
Click 이벤트 전/후에 발생할 이벤트의 인자를 전달한 EventArgs 클래스 입니다. 이미 지난 회차를 보신 분이라면 그렇게 생소하지 않을 것입니다.
///<summary>
/// Before 이벤트가발생할때전달될이벤트인자클래스입니다.
///</summary>
public class BeforeClickEventArgs : CancelEventArgs
{
public string Reason { get; set; }
}
///<summary>
/// After 이벤트가발생할때전달될이벤트인자클래스입니다.
///</summary>
public class AfterClickEventArgs : EventArgs { } |
또한, 직관적인 코딩을 위해 Before/After 이벤트를 위한 델리게이트를 선언하였습니다. 특별한 변경된 EventArgs 와 같은 인자가 없다면 기존 EventHandler 를 활용해도 되지만, 언제든 추후에 확장될 가능성은 충분하다고 생각합니다. 그렇기 때문에 델리게이트를 선언해 주었답니다.
///<summary>
/// BeforeClick 이벤트를캡슐화하는델리게이트입니다.
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
public delegate void BeforeClickEventHandler(object sender, BeforeClickEventArgs e);
///<summary>
/// AfterClick 이벤트를캡슐화하는델리게이트입니다.
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
public delegate void AfterClickEventHandler(object sender, AfterClickEventArgs e); |
여기서 이벤트는 사전(Dictionary) 을 통해 이벤트를 관리하게 됩니다. Umc.Core 프로젝트에 사용되는 EventHandlerDictionary 클래스의 일부를 직접 예제 클래스에 포함한 것입니다. 이 EventHandlerDictionary 에 접근하기 위한 Events 프로퍼티를 선언하였습니다.
private EventHandlerDictionary events;
///<summary>
/// EventHandlerDictionary 를통해이벤트를관리합니다.
///</summary>
protected EventHandlerDictionary Events
{
get
{
if( events == null )
events = new EventHandlerDictionary();
return events;
}
} |
여기에서 선언된 이벤트는 EventHandlerDictionary 클래스에서 관리하게 될 것이기 때문에, event 선언에 대해 커스트마이징(?)이 필요합니다. 즉, 이벤트의 추가/삭제에 대한 액션을 변경할 필요가 있습니다.
private object EVENT_BEFORE_CLICK = new object(); // BeforeClick 이벤트키오브젝트
private object EVENT_AFTER_CLICK = new object(); // AfterClick 이벤트키오브젝트
///<summary>
/// BeforeClick 이벤트입니다. Click 이벤트가발생하기전에발생합니다.
///</summary>
[Description("Click 이벤트가발생하기전에발생합니다")]
public event BeforeClickEventHandler BeforeClick
{
add
{
this.Events.AddHandler(EVENT_BEFORE_CLICK, value);
}
remove
{
this.Events.RemoveHandler(EVENT_BEFORE_CLICK, value);
}
}
///<summary>
/// AfterClick 이벤트입니다. Click 이벤트가발생한후발생합니다.
///</summary>
[Description("Click 이벤트가발생후에발생합니다")]
public event AfterClickEventHandler AfterClick
{
add
{
this.Events.AddHandler(EVENT_AFTER_CLICK, value);
}
remove
{
this.Events.RemoveHandler(EVENT_AFTER_CLICK, value);
}
} |
여기는 각각의 Before/After 이벤트를 발생하는 메서드와 CancelEventArgs 의 Cancel 프로퍼티를 검사하는 메서드가 존재합니다. OnEventsFire() 메서드를 눈여겨 보시면 될 것 같습니다.
///<summary>
/// BeforeClick 이벤트를발생합니다.
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
protected virtual void OnBeforeClick(object sender, BeforeClickEventArgs e)
{
if( !this.Events.Contains( EVENT_BEFORE_CLICK ) ) return;
BeforeClickEventHandler handler =
this.Events[ EVENT_BEFORE_CLICK ] as BeforeClickEventHandler;
if( handler != null )
handler(sender, e);
}
///<summary>
/// AfterClick 이벤트를발생합니다.
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
protected virtual void OnAfterClick(object sender, AfterClickEventArgs e)
{
if( !this.Events.Contains(EVENT_AFTER_CLICK) ) return;
AfterClickEventHandler handler =
this.Events[ EVENT_AFTER_CLICK ] as AfterClickEventHandler;
if( handler != null )
handler(sender, e);
}
///<summary>
/// Click 이벤트가발생할경우 BeforeClick/AfterClick 이벤트를발생합니다.
///</summary>
///<param name="sender"></param>
protected virtual void OnEventsFire( object sender )
{
BeforeClickEventArgs beforeArgs = new BeforeClickEventArgs();
OnBeforeClick( sender, beforeArgs );
if( beforeArgs.Cancel ) return;
AfterClickEventArgs afterArgs = new AfterClickEventArgs();
OnAfterClick( sender, afterArgs );
}
[Obsolete("ButtonEx 컨트롤에서는 Click 이벤트를사용하지않도록합니다. 대신 AfterClick 이벤트를사용하세요")]
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.Click += new EventHandler(ServerControl1_Click);
}
private void ServerControl1_Click(object sender, EventArgs e)
{
OnEventsFire(sender);
} |
이제 간략한 소스 코드 설명은 끝났네요. 힘들게 만든 ButtonEx 서버 컨트롤을 어떻게 활용하면 될지 다음 회차를 참고하세요.
'.NET > C#' 카테고리의 다른 글
[C# 4.0] Parallel Extension - [3] TPL(Task Parallel Library) (0) | 2008.03.01 |
---|---|
실전 event [6] - 취소 가능한 버튼 서버컨트롤 활용 (0) | 2007.12.18 |
실전 event [4] - 취소 가능한 이벤트 만들기 (0) | 2007.12.17 |
실전 event [3] - 취소 가능한 이벤트란 (0) | 2007.12.17 |
실전 event [2] - 유저컨트롤에서 페이지로 이벤트로 값 전달 (0) | 2007.12.16 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- 2,841,738
- Today
- 3
- Yesterday
- 47
링크
- ***** MY SOCIAL *****
- [SOCIAL] 페이스북
- [SOCIAL] 팀 블로그 트위터
- .
- ***** MY OPEN SOURCE *****
- [GITHUB] POWERUMC
- .
- ***** MY PUBLISH *****
- [MSDN] e-Book 백서
- .
- ***** MY TOOLS *****
- [VSX] VSGesture for VS2005,200…
- [VSX] VSGesture for VS2010,201…
- [VSX] Comment Helper for VS200…
- [VSX] VSExplorer for VS2005,20…
- [VSX] VSCmd for VS2005,2008
- .
- ***** MY FAVORITES *****
- MSDN 포럼
- MSDN 라이브러리
- Mono Project
- STEN
- 일본 ATMARKIT
- C++ 빌더 포럼
- .
TAG
- Managed Extensibility Framework
- test
- Windows 8
- 팀 파운데이션 서버
- github
- 엄준일
- ALM
- .NET Framework 4.0
- 비주얼 스튜디오
- umc
- ASP.NET
- Visual Studio 11
- Team Foundation Server
- Visual Studio
- Visual Studio 2010
- Silverlight
- c#
- testing
- Visual Studio 2008
- LINQ
- monodevelop
- mono
- Team Foundation Server 2010
- 비주얼 스튜디오 2010
- TFS
- TFS 2010
- 땡초
- .NET
- POWERUMC
- MEF
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 |
글 보관함
- 2020/05 (1)
- 2019/10 (3)
- 2018/11 (1)
- 2018/08 (2)
- 2017/04 (1)
- 2017/01 (2)
- 2016/11 (2)
- 2016/08 (1)
- 2016/05 (1)
- 2016/04 (2)
- 2016/02 (2)
- 2016/01 (1)
- 2015/05 (1)
- 2015/04 (2)
- 2015/03 (1)
- 2015/02 (1)
- 2015/01 (1)
- 2014/11 (1)
- 2014/09 (2)
- 2014/08 (2)
- 2014/05 (2)
- 2014/04 (3)
- 2014/03 (2)
- 2014/02 (2)
- 2014/01 (4)
- 2013/12 (2)
- 2013/11 (1)
- 2013/10 (2)
- 2013/09 (6)
- 2013/08 (3)