Winform - festzustellen, ob die Maussteuerung Benutzer verlassen hat
-
05-07-2019 - |
Frage
Ich kämpfe mit etwas, das ich denke, sollte sich leicht (er) sein. Ich habe ein Windows-Formular und eine flowgridlayout Leiste am unteren Rand des Formulars. Ich bevölkern sie dynamisch mit X Anzahl der User Controls Innerhalb dieser Form. Die Kontrollen sind alle vom gleichen Typ.
Das Ziel ist es, wenn der Benutzer die Maus über die Benutzersteuerung hoovers es eine andere Form öffnet und positioniert sie, wo die Maus ist. Wenn Maus, um die Form der geöffneten Form verlässt verschwindet.
Das funktioniert fast groß. Das Problem ist, wenn der Benutzer die Kontrolle etwas wie ein Etikett oder ein Textfeld im Inneren hat. Es gilt als die UC verlassen hat, so dass die Form verschwindet.
Mein Gedanke war dann den X und Y zu verwenden, zu sagen, ob es innerhalb der UC ist, aber ich kann das nicht begreifen.
Darf ich fragen:
1) Was ist der beste Ansatz für das? 2) Wie kann ich es codieren, wie die UC dynamisch sind ich kann nicht genau wissen, wo sie sein werden.
Danke
Bearbeiten
Ich versuche, die Mauszeiger, um herauszufinden, aber nicht dorthin zu gelangen. Der folgende Code ist in dem UC SmallTagBox_MouseLeave Ereignisse:
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
Ich verstehe nicht, wie p2 (seine Eltern) einen größeren Y-Wert relativ zum Bildschirm haben kann.
Lösung
Anspannen alle Steuerelemente MouseEnter- und Leave Ereignisse, dann herauszufinden, ob es sich noch in der Form ist ziemlich schmerzhaft ist. Eine einfache Timer kann den Job erledigen:
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();
}
}
Andere Tipps
Idea 1) Wenn die MouseLeave
Ereignis ausgelöst wird, können Sie die Mauskoordinaten (relativ zum Bildschirm überprüfen) und prüfen, ob sie innerhalb der Grenzen Ihres Usercontrol noch sind. Wenn sie sind, sollte man davon ausgehen, dass die Maus durch die Kontrolle passieren muss wieder außerhalb der Grenzen zu bekommen, und Sie können die Veranstaltung diesmal bedenkenlos ignorieren.
Idea 2) Bringen Sie MouseEnter
Event-Handler an die untergeordneten Steuerelemente. Dann, wenn die Maus betritt, wissen Sie, und können die Usercontrol MouseLeave
Ereignis ignorieren. Dann, wenn das MouseLeave
-Ereignis ausgelöst Kind, überprüfen Sie die MouseEnter
des Usercontrol wieder.
Ich glaube, ich würde ein Event-Handler für MouseLeave
für jedes Steuerelement hinzufügen, die Sie haben und die Parent
Eigenschaft verwenden, um die Benutzerkontrolle zu finden, nachdem Sie sind. Ich bin damit einverstanden, wird es aber ein bisschen schmerzhaft sein.
Sie können auch eine Schleife durch die alle untergeordneten Steuerelemente (rekursiv) auf Ihrer Kontrolle, und fügen Sie ein MouseEnter- und Mouseleave-Ereignis auf sich als gut.
Sie haben einige Buchhaltung zu tun, wenn die Maus in Ihrer Kontrolle ist, oder ein Kind Kontrolle.