닷넷프로그래밍정복 김상형저 가메출판사

이번 장은 완전히 실습장입니다.

 

시스템에서 발생하는 일체의 변화에 대한 정보를 메시지라고 하며 닷넷에서는 이벤트라고 부른다.

이벤트에 핸들러 추가하기

ex MyForm.Paint += new PaintEventHandler(MyPaint);

 

static void MyPaint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawEllipse(Pens.Blue, 10, 10, 200, 200);
            e.Graphics.DrawRectangle(Pens.Red, 10, 10, 150, 350);


        }

delegate로 선언되어있으니까 += 연산자를 이용해서 추가해주면 되고 인자는 object와 .이벤트인자를 넣어주면 된다

 

가장 메소드 재정의하기 - OnPaint는 Control class 정의되어 있고 protected이다. 이것을 재정의하는 방법이 있다. 객체에 속한 메소드이니까 메세지를 처리해주는 주체인 sender는 인수로 받지 않는다. 객체 자신인 this가 바로 sender이기때문이다. 핸들러 등록 없이 함수를 재정의하면 된다.

ex

 protected override void OnPaint(PaintEventArgs e)
        {
            //base.OnPaint(e);
            e.Graphics.DrawEllipse(Pens.Blue, 10, 10, 200, 200);
        }

Paint 이벤트에 핸들러를 추가하는 것과 OnPaint 가상메소드를 재정의하는 것의 차이는 무엇일까.

WM_PAINT메세지 발생시 프레임 워크가 OnPaint 메소드를 호출하도록 되어 있고 OnPaint 이벤트에 등록된 핸들러를 차례로 호출하도록 되어 있다. 즉 omPaint가 우선순위가 더 높다.

폼에서 OnPaint를 재정의하지 않으면 Control의 OnPaint가 호출되어 등록된 핸들러를 호출하지만 OmPaint 재정의 하면 이 코드가 실행되지 않으므로 등록된 핸들러가 어떤 것도 호출되지 않는다. WM_PAINT 메시지에 대해 두 메소드를 다 실행하려면

ex.

 protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e); // 반드시 있어야 한다. 2008에는 기본적으로 재정의 하면 나온다.
            e.Graphics.DrawEllipse(Pens.Blue, 10, 10, 200, 200);
        }

OnPaint 가상메소드는 프레임 워크에 의해 호출된다는 점에서 미리 설치된 이벤트 핸들러라고 할수 있다

 

마법사의 핸들러 작성

  1.  디자이너에서 이벤트를 처리할 객체를 선택한다
  2. 속성창의 이벤트 페이지에서 처리할 이벤트를 선택한다
  3. 마법사가 이벤트 핸들러를 생성하고 연결한다
  4. 핸들러 본체에 코드를 작성한다.

    가상메소드의 이름은 항상 이벤트 이름 앞에 전치사 On을 붙여서 정의한다. 예를 들어 Some 이벤트가 있다면  이 이벤트를 호출하는 가상메소드는 OnSome이다.

    이벤트중엔 사용하지 않는 것들도 있다. Close Event는 닷넷2.0이후에 FormClosed로 바꾸어 쓰지만 과거 호환성을 위해서 남아있다. SizeChanged 이벤트는 Resize Event와 동일하니 선택해서 사용하면 된다. LocationChanged Event와 Move Event도 동일하다 VB지원때문에 중복해서 정의되어 있다.

 

 

키보드 입력

  1. ex.

    public JForm()
            {
                InitializeComponent();
                str = "";
            }

            private void JForm_Paint(object sender, PaintEventArgs e)
            {
                //e.Graphics.DrawEllipse(Pens.Blue, 10, 10, 200, 200);
                e.Graphics.DrawString(str, Font, Brushes.Gold, 10, 10);
                //Update();
            }

            private void JForm_KeyPress(object sender, KeyPressEventArgs e)
            {
                //str += e.KeyChar;
                if(e.KeyChar == ' ')
                {
                    str = "";
                }
                else
                {
                    str += e.KeyChar;
                }
                Invalidate();
            }
    invalidate()는 화면을 무효화하여 차후 Paint 이벤트를 발생시키는 역할을 한다. 만약 Paint 이벤트를 즉시 처리하려면 Update()를 호출하거나 Invalidate와 Update를 같이 수행하는  Refresh 메소드를 호출해야 한다. 모든 그리기는 Paint 이벤트에서 해야 함을 유의한다.

- Form의 Size.Witdh/Height와 Width/Height는 같은 값인거 같다

마우스 입력

마우스 메세지

click event와 mouse click 이벤트의 차이.

mouse Click은 마우스에서 클릭이 일어났을때 발생하는 이벤트이고 컴포넌트에서 Enter 키 같은 것으로 클릭이 일어나면 발생하지 않는다.

click 이벤트는 모든 컴포넌트의 모든 종류의 클릭-마우스를 사용하던 말던-과 더블클릭 이벤트 발생시에 발생하는 이벤트이다. 그러므로 더블클릭의 경우 Click 이벤트는 두번발생한다.

 

휠마우스

스크롤 delta 는  default 는 120 이 가능하다.

속성창에 MouseWheel가 누락되어 있는 버그는 VS2005/VS2008 모두 수정되어 있지 않아서 직접 핸들러를 달아줘여 한다.

 

마우스의 들어오고 나오고 관리

마우스가 콘트롤 안에 들어가게 되면 MouseHover 이벤트가, 마우스가 콘트롤 밖으로 나가면 MouseLeave Event가 발생한다.

 

폼의 이벤트

  • Load - 폼이 로드되어 메모리로 올라올때, 그리고 화면에 표시되기 직전에 발생한다. 폼의 일회적인 초기화에 적합하다
  • FormClosed - 폼이 닫힐때, 즉 생애를 마치고 파괴될때 발생한다. Load에서 할당한 리소스를 이 이벤트에서 해제한다. 닷넷2.0이전엔 Closed 이벤트를 썼으나 FormClosed 바뀌었다
  • FormClosing - 폼이 닫히기 직전에 발생한다.

 

생성자와 Load 이벤트

생성자 대신에 Load이벤트 핸들로 초기화 할수 있다. 호출순서는 생성자 호출 다음에 Load 이벤트가 발생한다.

 

ex.

public JForm2()
        {
            //ar = new ArrayList();
            Status = "알수 없음";
            InitializeComponent();
            if (true)
            {
                MessageBox.Show("생성자 초기화에 실패하여 실행을 계속 할수 없습니다",
                    "이거나 이걸 어째");
                Close();

            }
        }

이 예제는 예외가 발생한다. 이유는 생성자가 하라는 초기화는 안 하고 close로 폼을 닫아버렸기때문이다.

 

크기변경

  • Resize - 콘트롤의 크기가 변경될 때, 즉 Size 프로퍼티가 바뀔때마다 발생한다. 별도의 인수는 전달되지 않으므로 변경되 크기는 sender 인수를 Control로 캐스팅한 후 Size 프로퍼티를 통해 조사해야 한다. 컨트롤이 최소 생성될때는 이 이벤트가 발생하지 않는다.
  • Layout - 폼의 크기가 바뀌거나 차일드의 위치를 변경할때 또는 차일드를 추가ㅡ 제거할떄마다 전달된다
  • SizeChanged - Resize와 동일한 이벤트
  • ClientSizeChanged - ClientSize 프로퍼티가 변경될때마다 발생한다. Resize 이벤트와 발생 시점이 거의 동일핟.

 

상태변화

폼의 상태나 프로퍼티가 조금이라도 바뀔때마다 각종 이벤트들이 발생한다. 프로퍼티의 변경에 대한 이벤트들은 공통적으로 ~Changed로 되어 있다.

  • Activard, Deactivated - 활성화 상태가 변경될때
  • Shown - 폼이 최초로 보일때 한번만 발생한다
  • GotFocus, LostFocus - 포커스 변경시 발생
  • VisibleChanged - Visible 속성이 변경될때 발생
  • ForeColorChanged, BAckColorChanged - 전경색, 배경색이 변경될때 발생
  • FontChanged - Font 프로퍼티가 변경될때 발생

이 중에 Shown 이벤트가 유용하다. 예를 들어 프로그램이(폼이) 뜬 상태에서 등록을 유도하는 메세지창을 띄우는 경우 유용하다. Load 이벤트를 쓴다면 폼이 로드되어 보이기 전에 실행되겠지만 Shown은 폼은 로드가 된 다음에 바로 실행된다는 장점이 있다, Win32에는 이에 대응하는 적절한 메세지가 없다.

 

 

이벤트 보기

이벤트는 정확한 발행 시점곽 순서를 아는 것이 중요하다. 닷넷에는 win32의 스파이 같은 프로그램이 없으므로 필요한 이벤트가 있다면 직접 등록해서 테스트해봐야 한다

 

타이머

시계 - 닷넷에서는 타이버는 Timer class로 표현한다. 하지만 얼추 일정한 간격으로 이벤트를 발생시킬뿐 실행환경에 따라서 발생주기가 어긋나기도 한다. 믿을수 없다.

ex.

 public partial class TimerForm : Form
    {
        private string Time;


        public TimerForm()
        {
            InitializeComponent();
        }

        private void TimerForm_Load(object sender, EventArgs e)
        {
            Timer T = new Timer();
            T.Interval = 1000;
            T.Tick += new EventHandler(Form1_Timer);
            T.Start();

        }

        private void TimerForm_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawString(Time, this.Font, Brushes.Black, 10, 10);
        }

        private void Form1_Timer(object sender, System.EventArgs e)
        {
            DateTime dt = DateTime.Now;
            Time = dt.Hour + " 시 " + dt.Minute + " 분 " + dt.Second + " 초 ";
            Invalidate();

        }

여기서 매번 Timer 이벤트가 발생할때마다 시각을 다시 조사하는 것은 Timer Event가 썩 믿음직 스럽지 않기때문에 확실한 값을 만들기 위해서 이다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

이 글은 스프링노트에서 작성되었습니다.

by 무위자연 2008. 8. 29. 16:59