Question

I am struggling with something that I think should be easily (ish). I have a windows form and a flowgridlayout panel at the bottom of the form. Inside this form I dynamically populate it with X number of User Controls. The controls are all the same type.

The goal is when the user hoovers the mouse over the user control it opens another form and positions it where the mouse is. When mouse leaves the form the opened form disappears.

This almost works great. The problem is when the User Control has anything like a label or text box inside it. It is considered to have left the UC so the form disappears.

My thought was then to use the X and Y to tell if it is inside the UC but I can not figure this out.

Can I ask:

1) What is the best approach to this? 2) How can I code it, as the UC's are dynamic I can not know exactly where they will be.

Thanks

EDIT

I am trying to figure out the mouse pointers but not getting there. The code below is within the UC SmallTagBox_MouseLeave event:

        Point loc = this.Location;
        Point p = this.PointToScreen(this.Location);
        Point p2 = this.PointToScreen(this.Parent.Location);

        Point ms = MousePosition;
        Rectangle screenBounds = new Rectangle(this.PointToScreen(this.Location), this.Size);
        if (!screenBounds.Contains(ms))
        {
            thw.Close();
            thw = null;
        }
  • loc {X = 275 Y = 3} System.Drawing.Point
  • p {X = 808 Y = 908} System.Drawing.Point
  • p {X = 808 Y = 908} System.Drawing.Point
  • p2 {X = 545 Y = 1542} System.Drawing.Point
  • ms {X = 574 Y = 914} System.Drawing.Point
  • screenBounds {X = 808 Y = 908 Width = 62 Height = 29} System.Drawing.Rectangle

I do not understand how p2 (its parent) can have a greater Y value relative to the screen.

Was it helpful?

Solution

Hooking all the controls MouseEnter and MouseLeave events, then figuring out if it is still inside the form is pretty painful. A simple timer can get the job done too:

  public partial class Form1 : Form {
    private Timer mTimer;
    public Form1() {
      InitializeComponent();
      mTimer = new Timer();
      mTimer.Interval = 200;
      mTimer.Tick += mTimer_Tick;
      mTimer.Enabled = true;
    }
    private void mTimer_Tick(object sender, EventArgs e) {
      if (!this.DesktopBounds.Contains(Cursor.Position)) this.Close();
    }
  }

OTHER TIPS

Idea 1) When the MouseLeave event fires, you can check the mouse coordinates (relative to screen) and check if they're still within the bounds of your usercontrol. If they are, it should be assumed that the mouse has to pass back through the control to get outside the bounds, and you can safely ignore the event this time.

Idea 2) Attach MouseEnter event handlers to the child controls. Then when the mouse enters one, you will know and can ignore the usercontrol's MouseLeave event. Then when the child's MouseLeave event fires, check for the usercontrol's MouseEnter again.

I think I would add an event handler for MouseLeave for every control that you have and use the Parent property to find the User Control you are after. I agree, it will be a bit painful though.

You can also loop through all the child controls (recursive) on your control, and attach a MouseEnter and MouseLeave event to them as well.

You have to do some bookkeeping if the mouse is in your control, or some child control.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top