비활성화된(Disabled) 컨트롤에 클릭 이벤트 전달받는 방법 C#

비활성화된 컨트롤


  C#을 코딩하다 보면 비활성화된 컨트롤(Enabled = false;)에 마치 클릭 이벤트가 적용된 것처럼 코딩해야 하는 때가 있습니다.

  그러나 컨트롤의 Enabled 속성이 false로 잡혀있다면 Click을 포함한 모든 이벤트를 받을 수가 없죠.

  그러나 예를 들어 초기 폼 로드 시 비활성화 상태였다가, 클릭하면 활성화가 되며 다른 컨트롤과도 연계돼 처리하는 방식의 코딩이 필요할 때가 많습니다. 이럴 땐 비활성화된 컨트롤에 클릭 이벤트를 받는 듯한 처리가 필요한데 어떻게 해야 할까요?

비활성화된 컨트롤에 클릭 이벤트 효과 내기


  방법은 간단합니다. 바로 부모 컨트롤의 MouseClick 이벤트를 넘겨받아 MouseEventArgs의 Location을 기초로 부모 컨트롤의 GetChildAtPoint(Point p) 메소드를 호출해 처리하는 방식입니다.

  예제를 드리자면 아래와 같겠네요.
CtrlParent.MouseClick += new MouseEventHandler((sender, e) => 
{
    var arg = e as MouseEventArgs;
    var pos = arg.Location;
    var ctrl = CtrlParent.ChildAtPoint(pos) as TextBox;

    if (ctrl != null)
    {
        // Processing...
    }
});


  우선 부모 컨트롤인 CtrlParent(여기선 System.Windows.Forms.Panel 타입) 컨트롤의 MouseClick 이벤트에 이벤트 핸들러를 등록합니다. 여기서 중요한 것이 이벤트 핸들러의 내용입니다.

  var arg = e as MouseEventArgs; 부분은 생략해주세요. 제가 블로그에 글 쓰는 속도를 단축하기 위해 람다 식으로 핸들러를 작성하느라 생긴 부분입니다.

  var pos = arg.Location; 이 부분에서 현재 컨트롤에 클릭 된 마우스 좌표를 얻어옵니다.
  var ctrl = CtrlParent.GetChildAtPoint(pos); 이제 부모 컨트롤(CtrlParent)에서 위치(pos)에 있는 자식 컨트롤을 ctrl 변수에 담아옵니다. 단, 이렇게 할 경우 타입이 Control이 되기 때문에 캐스팅을 해줍시다.
  var ctrl = CtrlParent.GetChildAtPoint(pos) as TextBox; 이제 ctrl 변수에 현재 클릭된 마우스 위치 바로 아래의 자식 컨트롤이 담겼습니다.

  이제 정말 중요한 부분입니다. 클릭 효과를 제대로 내려면 제대로 된 비교가 필요합니다. 바로 자식 컨트롤(ctrl)의 영역에 마우스 클릭 지점(pos)가 포함되는지 여부이죠. 포함된다면 클릭 이벤트가 발생한 상황과 동등한 상황이 될 것이고, 포함되지 않는다면 아닐 것입니다.
  ctrl.ClientRectangle(바운드 영역)에 pos(마우스 클릭 지점)이 포함돼 있다면 클릭 이벤트가 발생한 것이고, 그렇지 않다면 발생하지 않은 것이므로 if문으로 분기 처리해 작업하시면 됩니다.

댓글

이 블로그의 인기 게시물

C# 남아도는 메모리에도 불구하고 OutOfMemoryException이 발생한다면?

MySQL 데이터 타입과 Java 데이터 타입 비교/매칭

테일즈위버 OST 전곡 모음