문제

나는 마우스 커서가 일련의 좌표 사이에 떨어지면 발사 해야하는 특정 형태의 Mouseclick 이벤트를 처리하려고 노력하고 있습니다.

나는 빈 양식이 있다면 단순히 MouseMove 이벤트에 묶을 수 있고 나가는 것을 이해합니다. 그러나 실제로 최대 10 개의 다른 중첩 컨트롤이있을 수 있으며 테스트 앱에서 MouseMove 이벤트는 커서가 실제 형태 자체에 있고 아동 통제를 통제 할 경우에만 해고됩니다.

디자인 시간에 알려지지 않은 수의 아동 컨트롤이있을 때이 이벤트를 처리하는 방법을 아는 사람이 있습니까?

내가 사용할 수있는 쉬운 1 라이너가 있습니까?

도움이 되었습니까?

해결책

IMHO 여기에는 약간의 이진 상황이 있습니다. "하나의 라이너"는 없습니다. 내가 볼 수있는 유일한 해결책은 이벤트를 .net 컨테이너로 구현하지 않는 컨트롤을 얻는 것입니다.

컨트롤이 클릭되면 정상적인 예상 동작은 양식의 활발한 제어가 될 것입니다 (이것은 항상 this.activcecontrol에 의해 액세스 할 수 있음).

그러나 클릭 한 컨트롤이 마우스를 캡처하는 경우, .NET이 이벤트가 "버블 링"(WPF와 마찬가지로)을 구현하지 않기 때문에 이벤트를 제기해야합니다.

밀봉 된 객체의 확장 동작이나 확장 방법을 작성하는 것이 무엇이든, 제어를위한 확장을 작성하는 것을 발견했지만이 경우 도움이 될지 모르겠습니다. 불행히도 나는 지금 내 고국에서 나왔고, 비주얼 스튜디오가 없습니다.

양식의 주어진 지점이 컨트롤의 범위 내에 있는지 여부를 결정하는 데 사용할 수있는 한 가지 전략 중 하나는 양식 제어 (this.controls)를 통해 양식의 모든 제어 영역 (경계)을 열거하는 것입니다. 그러나 겹치는 컨트롤이 있다면 주어진 지점을 포함하는 둘 이상의 컨트롤 문제가 있습니다.

최고, Bill

다른 팁

이 시도:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        AddMouseMoveHandler(this);
    }

    private void AddMouseMoveHandler(Control c)
    {
        c.MouseMove += MouseMoveHandler;
        if(c.Controls.Count>0)
        {
            foreach (Control ct in c.Controls)
                AddMouseMoveHandler(ct);
        }
    }

    private void MouseMoveHandler(object sender, MouseEventArgs e)
    {
        lblXY.Text = string.Format("X: {0}, Y:{1}", e.X, e.Y);
    }
}

이 게시물이 꽤 오래되었음을 알고 있지만 가장 간단한 방법은 양식이 구현하는 것 같습니다. IMessageFilter. 생성자 (또는 IN OnHandleCreated) 당신은 전화합니다

Application.AddMessageFilter(this);

그런 다음 구현에서 모든 창의 메시지를 잡을 수 있습니다. IMessageFilter.PreFilterMessage.

Win32 Ischild 메소드에 p/호출을 사용해야 할 것입니다.

[DllImport("user32.dll")]
public static extern bool IsChild(IntPtr hWndParent, IntPtr hWnd);

양식과 함께 Handle 올바른 메시지를 처리하는지 확인하는 속성.

컨트롤 마우스 오버 이벤트 핸들러를 사용하지 않는 이유는 무엇입니까?

나는 펀치에 조금 늦었다는 것을 알고 있지만, 패널을 제목 바로 사용할 때 오늘이 일찍이 문제를 겪고있었습니다. 텍스트, 그림 박스 및 몇 개의 버튼이 모두 패널 내에 중첩 된 라벨이 있었지만 MouseMove 이벤트를 가두어 야했습니다.

내가 결정한 것은이 작업을 수행하기 위해 재귀 적 방법 핸들러를 구현하는 것이 었습니다. 1 레벨의 중첩 컨트롤 만 있었기 때문에 말도 안되는 레벨의 중첩에 접근하기 시작할 때 과도하게 확장되지 않을 수 있습니다.

내가 한 방법은 다음과 같습니다.

    protected virtual void NestedControl_Mousemove(object sender, MouseEventArgs e)
    {
        Control current = sender as Control;
        //you will need to edit this to identify the true parent of your top-level control. As I was writing a custom UserControl, "this" was my title-bar's parent.
        if (current.Parent != this) 
        {
            // Reconstruct the args to get a correct X/Y value.
            // you can ignore this if you never need to get e.X/e.Y accurately.
            MouseEventArgs newArgs = new MouseEventArgs
            (
                e.Button, 
                e.Clicks, 
                e.X + current.Location.X, 
                e.Y + current.Location.Y, 
                e.Delta
            );
            NestedControl_Mousemove(current.Parent, newArgs);
        }
        else
        {
            // My "true" MouseMove handler, called at last.
            TitlebarMouseMove(current, e);
        }
    }

    //helper method to basically just ensure all the child controls subscribe to the NestedControl_MouseMove event.
    protected virtual void AddNestedMouseHandler(Control root, MouseEventHandler nestedHandler)
    {
        root.MouseMove += new MouseEventHandler(nestedHandler);
        if (root.Controls.Count > 0)
            foreach (Control c in root.Controls)
                AddNestedMouseHandler(c, nestedHandler);
    }

그런 다음 설정하는 것은 비교적 간단합니다.

"진정한"핸들러 정의 :

    protected virtual void TitlebarMouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            this.Text = string.Format("({0}, {1})", e.X, e.Y);
        }
    }

그런 다음 Controls 이벤트 가입자를 설정합니다.

//pnlDisplay is my title bar panel.
AddNestedMouseHandler(pnlDisplay, NestedControl_Mousemove);

사용하기가 비교적 간단하고 사실을 보증 할 수 있습니다. :)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top