控件在C#Windows程序中隐藏表单的事件

时间:2022-02-10 15:06:44

I had written an event handler for MouseMove for my form but When I add a panel to form, this handler does NOT run while mouse moves on panel. I added event handler to panel and this works but I had several panels on the form, is there an easier solution?

我为我的表单编写了一个MouseMove的事件处理程序但是当我添加一个面板来形成时,当鼠标在面板上移动时,这个处理程序不会运行。我向面板添加了事件处理程序,这可以工作,但我在表单上有几个面板,是否有更简单的解决方案?

8 个解决方案

#1


You could Implement IMessageFilter to pre-process messages that are going to your controls.

您可以实现IMessageFilter来预处理进入控件的消息。

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

However, I don't think this is a very clean way to do things from a design perspective.

但是,从设计的角度来看,我不认为这是一种非常干净的方式。

#2


Unfortunately, WinForms doesn't support event bubbling. But you can write some code to ease the task of hooking up events.

不幸的是,WinForms不支持事件冒泡。但是你可以编写一些代码来简化连接事件的任务。

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

        control.MouseMove += PanelMouseMove;
    }
}

You should call the above code passing it your current form and it will assign PanelMouseMove as event handler for MouseMove event of all the panels.

您应该调用以上代码将其传递给当前表单,并将PanelMouseMove指定为所有面板的MouseMove事件的事件处理程序。

#3


I think you should be able to "propagate" the handlers, so you don't have to re-write the code in each one. Just remember that the MouseMove event has control-relative coordinates, so if you pass the event from your panel to your form, you'll have to translate the X & Y values in the event to the form coordinates (something like subtracting panel.location.X from event.X, etc).

我认为你应该能够“传播”处理程序,所以你不必在每个代码中重写代码。请记住MouseMove事件具有控件相对坐标,因此如果您将事件从面板传递到表单,则必须将事件中的X和Y值转换为表单坐标(类似于减去panel.location来自event.X的.X等)。

#4


This code worked for me (assumes you have a form with a panel and a label. The label is named "MouseCoords"

此代码适用于我(假设您有一个带有面板和标签的表单。该标签名为“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;
        }
    }
}

#5


No there is no simpler way, and you should assign event handler for each control where you need to receive MouseMove events.

没有更简单的方法,您应该为每个需要接收MouseMove事件的控件分配事件处理程序。

#6


If you set the Capture property of the form to true, it will receive all mouse input, regardless of which control that is under the mouse. It will lose the mouse capture at certain operations (I am not sure exactly when, though). Also, according to the documentation for the property, shortcut keys should not work while the mouse is captured. So, depending on what you want to achieve, this might not be the preferred way to go.

如果将窗体的Capture属性设置为true,它将接收所有鼠标输入,而不管鼠标下的哪个控件。它会在某些操作中丢失鼠标捕获(但我不确定是什么时候)。此外,根据属性的文档,快捷键在捕获鼠标时不起作用。因此,根据您想要实现的目标,这可能不是首选方式。

#7


Assuming that mouse starts moving over the form rather than over the panel - which is a big assumption - you'll get a MouseLeave event when it enters a sub control. You could check the cursor location and call the mouse move code if it's still within the bounds of the form.

假设鼠标开始在窗体上移动而不是在面板上移动 - 这是一个很大的假设 - 当它进入子控件时你会得到一个MouseLeave事件。您可以检查光标位置并调用鼠标移动代码,如果它仍在表单的范围内。

This doesn't work if the mouse move event starts on a control.

如果鼠标移动事件在控件上启动,则不起作用。

#8


I found another solution :) "Raise events in controls which hide events" I catch the event in panel and rise the Mouse move event of the form by calling onMouseMove

我找到了另一个解决方案:)“在控件中引发事件隐藏事件”我在面板中捕获事件并通过调用onMouseMove来提升表单的鼠标移动事件

#1


You could Implement IMessageFilter to pre-process messages that are going to your controls.

您可以实现IMessageFilter来预处理进入控件的消息。

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

However, I don't think this is a very clean way to do things from a design perspective.

但是,从设计的角度来看,我不认为这是一种非常干净的方式。

#2


Unfortunately, WinForms doesn't support event bubbling. But you can write some code to ease the task of hooking up events.

不幸的是,WinForms不支持事件冒泡。但是你可以编写一些代码来简化连接事件的任务。

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

        control.MouseMove += PanelMouseMove;
    }
}

You should call the above code passing it your current form and it will assign PanelMouseMove as event handler for MouseMove event of all the panels.

您应该调用以上代码将其传递给当前表单,并将PanelMouseMove指定为所有面板的MouseMove事件的事件处理程序。

#3


I think you should be able to "propagate" the handlers, so you don't have to re-write the code in each one. Just remember that the MouseMove event has control-relative coordinates, so if you pass the event from your panel to your form, you'll have to translate the X & Y values in the event to the form coordinates (something like subtracting panel.location.X from event.X, etc).

我认为你应该能够“传播”处理程序,所以你不必在每个代码中重写代码。请记住MouseMove事件具有控件相对坐标,因此如果您将事件从面板传递到表单,则必须将事件中的X和Y值转换为表单坐标(类似于减去panel.location来自event.X的.X等)。

#4


This code worked for me (assumes you have a form with a panel and a label. The label is named "MouseCoords"

此代码适用于我(假设您有一个带有面板和标签的表单。该标签名为“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;
        }
    }
}

#5


No there is no simpler way, and you should assign event handler for each control where you need to receive MouseMove events.

没有更简单的方法,您应该为每个需要接收MouseMove事件的控件分配事件处理程序。

#6


If you set the Capture property of the form to true, it will receive all mouse input, regardless of which control that is under the mouse. It will lose the mouse capture at certain operations (I am not sure exactly when, though). Also, according to the documentation for the property, shortcut keys should not work while the mouse is captured. So, depending on what you want to achieve, this might not be the preferred way to go.

如果将窗体的Capture属性设置为true,它将接收所有鼠标输入,而不管鼠标下的哪个控件。它会在某些操作中丢失鼠标捕获(但我不确定是什么时候)。此外,根据属性的文档,快捷键在捕获鼠标时不起作用。因此,根据您想要实现的目标,这可能不是首选方式。

#7


Assuming that mouse starts moving over the form rather than over the panel - which is a big assumption - you'll get a MouseLeave event when it enters a sub control. You could check the cursor location and call the mouse move code if it's still within the bounds of the form.

假设鼠标开始在窗体上移动而不是在面板上移动 - 这是一个很大的假设 - 当它进入子控件时你会得到一个MouseLeave事件。您可以检查光标位置并调用鼠标移动代码,如果它仍在表单的范围内。

This doesn't work if the mouse move event starts on a control.

如果鼠标移动事件在控件上启动,则不起作用。

#8


I found another solution :) "Raise events in controls which hide events" I catch the event in panel and rise the Mouse move event of the form by calling onMouseMove

我找到了另一个解决方案:)“在控件中引发事件隐藏事件”我在面板中捕获事件并通过调用onMouseMove来提升表单的鼠标移动事件