Parent Control Mouse Enter/Leave Events With Child Controls

前端 未结 5 1072
天涯浪人
天涯浪人 2020-11-27 18:49

I have a C# .NET 2.0 WinForms app. My app has a control that is a container for two child controls: a label, and some kind of edit control. You can think of it like this,

5条回答
  •  感动是毒
    2020-11-27 19:06

    I feel I found a much better solution than the currently top accepted solution.

    The problem with other proposed solutions is that they are either fairly complex (directly handling lower level messages).

    Or they fail corner cases: relying on the mouse position on MouseLeave can cause you to miss the mouse exiting if the mouse goes straight from inside a child control to outside the container.

    While this solution isn't entirely elegant, it is straightforward and works:

    Add a transparent control that takes up the entire space of the container that you want to receive MouseEnter and MouseLeave events for.

    I found a good transparent control in Amed's answer here: Making a control transparent

    Which I then stripped down to this:

    public class TranspCtrl : Control
    {
        public TranspCtrl()
        {
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.Opaque, true);
            this.BackColor = Color.Transparent;
        }
    
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle = cp.ExStyle | 0x20;
                return cp;
            }
        }
    }
    

    Example usage:

    public class ChangeBackgroundOnMouseEnterAndLeave
    {
        public Panel Container;
        public Label FirstLabel;
        public Label SecondLabel;
    
        public ChangeBackgroundOnMouseEnterAndLeave()
        {
            Container = new Panel();
            Container.Size = new Size(200, 60);
    
            FirstLabel = new Label();
            FirstLabel.Text = "First Label";
            FirstLabel.Top = 5;
    
            SecondLabel = new Label();
            SecondLabel.Text = "Second Lable";
            SecondLabel.Top = 30;
    
            FirstLabel.Parent = Container;
            SecondLabel.Parent = Container;
    
            Container.BackColor = Color.Teal;
    
            var transparentControl = new TranspCtrl();
            transparentControl.Size = Container.Size;
    
            transparentControl.MouseEnter += MouseEntered;
            transparentControl.MouseLeave += MouseLeft;
    
            transparentControl.Parent = Container;
            transparentControl.BringToFront();
        }
    
        void MouseLeft(object sender, EventArgs e)
        {
            Container.BackColor = Color.Teal;
        }
    
        void MouseEntered(object sender, EventArgs e)
        {
            Container.BackColor = Color.Pink;
        }
    }
    
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
    
            var test = new ChangeBackgroundOnMouseEnterAndLeave();
            test.Container.Top = 20;
            test.Container.Left = 20;
            test.Container.Parent = this;
        }
    }
    

    Enjoy proper MouseLeave and MouseEnter events!

提交回复
热议问题