2009-07-02 5 views
0

내 양식에 대해 MouseMove 이벤트 처리기를 작성했지만 폼에 패널을 추가 할 때 마우스가 패널로 이동하는 동안이 핸들러가 실행되지 않습니다. 패널에 이벤트 핸들러를 추가했는데 작동하지만 폼에 여러 개의 패널이 있습니다. 더 쉬운 솔루션이 있습니까?컨트롤은 C# Windows 프로그램에서 폼의 이벤트를 숨 깁니다.

+0

무엇을하려고합니까? –

+0

두 개의 패널이있는 양식이 있습니다. –

답변

0

당신이가는 메시지 프로세스 사전의 IMessageFilter을 구현할 수라는 당신의 를 제어합니다.

http://blogs.msdn.com/csharpfaq/archive/2004/10/20/245412.aspx

그러나, 나는이 디자인 관점에서 일을 할 수있는 매우 깨끗한 방법이라고 생각하지 않습니다.

+0

저는 그 기사를 읽었을뿐입니다. 아마도 그게 해결책 일 것입니다. –

+0

매우 유용한 기사 였지만 간단한 방법을 찾고있었습니다.) –

+0

Thanks OG. 나는 당신의 접근 방식을 구현했습니다. –

0

아니요 간단한 방법이 없으므로 MouseMove 이벤트를 받아야하는 각 컨트롤에 이벤트 처리기를 할당해야합니다.

1

나는 당신이 핸들러를 "전파"할 수 있어야한다고 생각한다. 그래서 각각의 코드를 다시 작성할 필요가 없다. MouseMove 이벤트의 좌표는 입니다. 컨트롤의 상대 좌표는입니다. 따라서 패널에서 이벤트를 폼으로 전달할 경우 이벤트의 X & Y 값을 폼 좌표로 변환해야합니다 (패널 빼기 . location.X from event.X 등).

0

폼의 Capture 속성을 true로 설정하면 마우스 아래에있는 컨트롤에 관계없이 모든 마우스 입력을 받게됩니다. 특정 작업에서 마우스 캡처를 잃을 것입니다 (정확히 언제인지는 확실하지 않습니다). 또한 속성에 대한 설명서에 따라 마우스를 캡처하는 동안 바로 가기 키가 작동하지 않아야합니다. 그래서, 당신이 달성하기를 원하는 것에 따라, 이것이 선호되는 방법이 아닐 수도 있습니다.

+0

캡쳐는 대부분 드래그 작업을 위해 예약되어 있습니다.이 경우 다른 모든 컨트롤이 마우스 상호 운용성을 잃어 버리기 때문입니다. – arbiter

2

불행히도 WinForms는 이벤트 버블 링을 지원하지 않습니다. 그러나 이벤트 연결을 쉽게하기위한 코드를 작성할 수 있습니다.

public void AssignMouseMoveEvent(Form form) 
{ 
    foreach(Control control in form.Controls) 
    { 
     if(! (control is Panel)) 
      continue; 

     control.MouseMove += PanelMouseMove; 
    } 
} 

당신은 그것을 현재 양식을 통과하는 위의 코드를 호출해야하며 모든 패널의 MouseMove 이벤트에 대한 이벤트 핸들러로 PanelMouseMove을 할당합니다.

+1

PanelMouseMove 이벤트 핸들러의 e.Location은 MouseMove 이벤트를 발생시키는 컨트롤을 기준으로합니다. –

+0

그게 저자가 필요로하는 것 같아요, 그렇죠? – SolutionYogi

+0

작성자가 모든 마우스 입력 받기 양식을 갖기를 원한다면 마우스가 움직이는 컨트롤이 아닌 좌표가 폼에 상대적이라면 선호 할 것이라고 생각합니다. ClientToScreen 및 ScreenToClient에 대한 두어 번 호출로 쉽게 해결할 수 있습니다. 저자가이를 알리고 싶었습니다. –

0

마우스가 패널보다는 폼 위로 이동하기 시작한다고 가정하면 큰 가정이지만 하위 컨트롤에 들어가면 MouseLeave 이벤트가 발생합니다. 폼의 경계 내에있는 경우 커서 위치를 확인하고 마우스 이동 코드를 호출 할 수 있습니다.

마우스 이동 이벤트가 컨트롤에서 시작되면 작동하지 않습니다.

1

이 코드는 패널과 레이블이있는 형태를 가정합니다 (나를 위해 일했다. 레이블은 "MouseCoords"

 

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 

namespace WindowsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void ShowCoords(int x, int y) 
     { 
      this.MouseCoords.Text = string.Format("({0}, {1})", x, y); 
     } 

     private void Form1_MouseMove(object sender, MouseEventArgs e) 
     { 
      this.ShowCoords(e.X, e.Y); 
     } 

     protected override void OnControlAdded(ControlEventArgs e) 
     { 
      // hook the mouse move of any control that is added to the form 
      base.OnControlAdded(e); 
      e.Control.MouseMove += new MouseEventHandler(Control_MouseMove); 
     } 

     private void Control_MouseMove(object sender, MouseEventArgs e) 
     { 
      // convert the mouse coords from control codes to screen coords 
      // and then to form coords 
      System.Windows.Forms.Control ctrl = (System.Windows.Forms.Control)sender; 
      Point pt = this.PointToClient(ctrl.PointToScreen(e.Location)); 
      this.ShowCoords(pt.X, pt.Y); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      this.MouseMove += this.Form1_MouseMove; 
     } 
    } 
} 
+0

이 기술에 익숙합니다. 그러나 많은 컨트롤에 동일한 핸들러를 할당 할 때 성능에 미치는 영향은 무엇입니까? –

+0

테스트를 해보지 만 성능에 미치는 영향은 최소화되어야합니다. 한 번에 하나의 컨트롤 만 이벤트 처리기를 호출합니다. 이는 컨트롤 당 대리자를 인스턴스화한다는 의미입니다. 대리자는 함수에 대한 형식 있고 안전한 고급 포인터입니다 (함수의 "코드 세그먼트"는 한 번만 존재하며 참조를 만드는 경우). 여전히 많은 톤의 컨트롤이 있다면 테스트 할 수있는 메모리 영향을 볼 수 있습니다. OnControlAdded 메서드를 주석으로 처리하고 메모리 사용을 비교합니다. – JMarsch

+0

(oh, 1 quid-pro-quo) : 무언가 (anythign)를 mousemove 내부에서 수행 할 때의 영향 은 성능에 영향을 미칠 수 있습니다. 마우스 이동은 매우 자주 발생합니다. 내 이전의 의견을 더 정확하게하려면 동일한 처리기를 참조하는 여러 컨트롤의 비용이 낮아야하지만 마우스 이동 핸들러에서 많은 작업을 수행하면 전반적인 성능에 영향을 미칠 수 있다고 생각합니다. – JMarsch

0

다른 해결책을 찾았습니다. "이벤트를 숨기는 컨트롤에서 이벤트 발생" onMouseMove를 호출하여 폼의 마우스 이동 이벤트를 발생시킵니다.

관련 문제