c# 检测鼠标在任何地方的点击(表单内部和外部)

Hel*_*ion 4 c# forms mouse click winforms

这是否可以在 if 语句中的任何位置(表单内部和外部)检测鼠标单击(左/右)?如果可能,怎么做?

if(MouseButtons.LeftButton == MouseButtonState.Pressed){

...

}
Run Code Online (Sandbox Code Playgroud)

suj*_*lil 5

当用户在表单控件外单击时,它会失去焦点,您可以使用它。这意味着您必须使用_Deactivate(object sender, EventArgs e)表单控件的事件来完成这项工作。因为 which 将在表单失去焦点并且不再是活动表单时触发。让Form1是形式,那么事件将如下所示:

private void Form1_Deactivate(object sender, EventArgs e)
{
    // Your code here to handle this event
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*țea 5

这是一个初学者,如果我理解您对“从窗口外点击”的需求,而 Hans Passant 的建议不符合您的需求。您可能需要为Form1_Click.

注意:提供此代码是为了说明该概念。此示例中的线程同步不是 100% 正确的。检查此答案的历史,以尝试更“线程正确”的答案,该答案有时会引发异常。作为替代方案,要摆脱所有线程问题,您可以让 StartWaitingForClickFromOutside 中的任务始终运行(也就是始终处于“侦听”模式),而不是尝试检测“表单内”或“表单外” " 状态并相应地开始/停止循环。

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

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

            this.MouseLeave += Form1_MouseLeave;
            this.Leave += Form1_Leave;
            this.Deactivate += Form1_Deactivate;
            this.MouseEnter += Form1_MouseEnter;
            this.Activated += Form1_Activated;
            this.Enter += Form1_Enter;
            this.VisibleChanged += Form1_VisibleChanged;
        }

        private AutoResetEvent are = new AutoResetEvent(false);

        // You could create just one handler, but this is to show what you need to link to
        private void Form1_MouseLeave(object sender, EventArgs e) => StartWaitingForClickFromOutside();
        private void Form1_Leave(object sender, EventArgs e) => StartWaitingForClickFromOutside();
        private void Form1_Deactivate(object sender, EventArgs e) => StartWaitingForClickFromOutside();
        private void StartWaitingForClickFromOutside()
        {
            are.Reset();
            var ctx = new SynchronizationContext();

            var task = Task.Run(() =>
            {
                while (true)
                {
                    if (are.WaitOne(1)) break;
                    if (MouseButtons == MouseButtons.Left)
                    {
                        ctx.Send(CLickFromOutside, null);
                        // You might need to put in a delay here and not break depending on what you want to accomplish
                        break;
                    }
                }
            });
        }

        private void CLickFromOutside(object state) => MessageBox.Show("Clicked from outside of the window");
        private void Form1_MouseEnter(object sender, EventArgs e) => are.Set();
        private void Form1_Activated(object sender, EventArgs e) => are.Set();
        private void Form1_Enter(object sender, EventArgs e) => are.Set();
        private void Form1_VisibleChanged(object sender, EventArgs e)
        {
            if (Visible) are.Set();
            else StartWaitingForClickFromOutside();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我对您的理解有误,您可能会发现这很有用:将子控件的点击事件传递给父控件