Обработка события нажатия в любом месте панели в C # - PullRequest
6 голосов
/ 13 октября 2010

В моей форме есть панель с обработчиком события щелчка.У меня также есть некоторые другие элементы управления внутри панели (ярлык, другие панели и т. Д.).Я хочу, чтобы событие щелчка регистрировалось, если вы нажмете где-нибудь внутри панели.Событие click работает до тех пор, пока я не нажимаю ни на один из элементов управления внутри панели, но хочу запустить событие независимо от того, где вы щелкнули внутри панели.Возможно ли это без добавления одинакового события щелчка ко всем элементам управления внутри панели?

Ответы [ 4 ]

5 голосов
/ 13 октября 2010

Технически это возможно, хотя это очень безобразно. Вам нужно перехватить сообщение до того, как оно будет отправлено в элемент управления, по которому щелкнули. Что вы можете сделать с IMessageFilter, вы можете прослушать входное сообщение, которое было удалено из очереди сообщений, прежде чем оно будет отправлено. Как это:

using System;
using System.Drawing;
using System.Windows.Forms;

class MyPanel : Panel, IMessageFilter {
    public MyPanel() {
        Application.AddMessageFilter(this);
    }
    protected override void Dispose(bool disposing) {
        if (disposing) Application.RemoveMessageFilter(this);
        base.Dispose(disposing);
    }
    public bool PreFilterMessage(ref Message m) {
        if (m.HWnd == this.Handle) {
            if (m.Msg == 0x201) {  // Trap WM_LBUTTONDOWN
                Point pos = new Point(m.LParam.ToInt32());
                // Do something with this, return true if the control shouldn't see it
                //...
                // return true
            }
        }
        return false;
    }
}
1 голос
/ 13 октября 2010

Мне нужна была та же самая функциональность сегодня, поэтому она протестирована и работает:

1: Создайте субклассер, который может захватывать ваш щелчок мышью:

internal class MessageSnatcher : NativeWindow
{
    public event EventHandler LeftMouseClickOccured = delegate{};

    private const int WM_LBUTTONDOWN = 0x201;
    private const int WM_PARENTNOTIFY = 0x210;

    private readonly Control _control;

    public MessageSnatcher(Control control)
    {
        if (control.Handle != IntPtr.Zero)
            AssignHandle(control.Handle);
        else
            control.HandleCreated += OnHandleCreated;

        control.HandleDestroyed += OnHandleDestroyed;
        _control = control;
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_PARENTNOTIFY)
        {
            if (m.WParam.ToInt64() == WM_LBUTTONDOWN)
                LeftMouseClickOccured(this, EventArgs.Empty);
        }

        base.WndProc(ref m);
    }

    private void OnHandleCreated(object sender, EventArgs e)
    {
        AssignHandle(_control.Handle);
    }

    private void OnHandleDestroyed(object sender, EventArgs e)
    {
        ReleaseHandle();
    }
}

2: Инициализируйте захватподключиться к панели WndProc:

    private MessageSnatcher _snatcher;

    public Form1()
    {
        InitializeComponent();

        _snatcher = new MessageSnatcher(this.panel1);
    }

3: похититель сообщений получит WM_PARENTNOTIFY, если вы нажмете на дочерний элемент управления.

0 голосов
/ 26 февраля 2018

Немного опоздал на вечеринку, но я сделал, чтобы отобразить все события щелчка всех элементов управления внутри панели на событие щелчка панели. Я знаю его противный подход. но эй !!

0 голосов
/ 13 октября 2010

Раньше вы имели возможность переопределять метод OnBubbleEvent в элементе управления.В WPF механизм называется Routed events: http://weblogs.asp.net/vblasberg/archive/2010/03/30/wpf-routed-events-bubbling-several-layers-up.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...