2010-09-26 5 views
13

Ich baue ein Windows Presentation Foundation-Steuerelement mit Microsoft Blend.WPF Mousepdown => Nein MouseLeave Ereignis

Wenn ich meine Kontrolle durch Drücken der linken Maustaste verlasse, wird das MouseLeave-Event nicht ausgelöst. Warum nicht?

+0

Was ist in Ihrer Kontrolle? Ich denke, dass dies daran liegt, dass das Objekt (z.B.Ein Button) in Ihrem Steuerelement, das das MouseDown-Ereignis empfangen hat, hat "Mouse.IsCaptured" auf "true" gesetzt, sodass es ausschließlich die MouseEvents behandelt. – ASanch

+0

Das ist nur ein Rand, Raster, Bild und 2 Etiketten. Ist das möglich? –

+0

Wir haben das gleiche Problem (siehe die Frage: http://stackoverflow.com/questions/15970248/wpf-mouse-leave-event-doesnt-trigger-with-mouse-down). Also habe ich hier eine Prämie angefangen, um Aufmerksamkeit zu erregen. – SiberianGuy

Antwort

7

Dieses Verhalten ist beabsichtigt: Wenn Sie mousedown auf einer Steuer- und Verlassen des Steuer tun, STILL die Kontrolle behält seine "Capture" auf der Maus, dh das Steuerelement wird nicht ausgelöst MouseLeave-Event. Das Maus-Verlassen-Ereignis wird stattdessen ausgelöst, sobald die Maustaste außerhalb des Steuerelements freigegeben wird.

Um dies zu vermeiden, können Sie einfach Ihre Steuer sagen die Maus überhaupt zu erfassen:

private void ControlMouseDown(System.Object sender, System.Windows.Forms.MouseEventArgs e) 
{ 
    Control control = (Control) sender; 
    control.Capture = false; //release capture. 
} 

Nun ist die Leave-Ereignis auch ausgelöst werden, wenn bewegen, während eine Taste gedrückt wird.

Wenn Sie das Capture in der Steuer benötigen, müssen Sie in mehr Mühe geben:

  • Starten Sie die mouseposition manuell Tracking, wenn die Maustaste gedrückt wird

  • Vergleichen Sie die Position mit den Top , Left und Size Attribute des betreffenden Steuerelements.

  • Entscheiden Sie, ob Sie die Steuerung stoppen müssen, um Ihre Maus zu erfassen oder nicht.

    public partial class Form1 : Form 
    { 
    private Point point; 
    private Boolean myCapture = false; 
    
    public Form1() 
    { 
        InitializeComponent(); 
    } 
    
    private void button1_MouseDown(object sender, MouseEventArgs e) 
    { 
        myCapture = true; 
    } 
    
    private void button1_MouseMove(object sender, MouseEventArgs e) 
    { 
        if (myCapture) 
        { 
         point = Cursor.Position; 
    
         if (!(point.X > button1.Left && point.X < button1.Left + button1.Size.Width && point.Y > button1.Top && point.Y < button1.Top + button1.Size.Height)) 
         { 
          button1.Capture = false; //this will release the capture and trigger the MouseLeave event immediately. 
          myCapture = false; 
         } 
        } 
    } 
    
    private void button1_MouseLeave(object sender, EventArgs e) 
    { 
        MessageBox.Show("Mouse leaving"); 
    } 
    

    }

natürlich müssen Sie die eigene Tracking (myCapture=false;) auf MouseUp stoppen. Vergessen, dass man :)

+1

Aber was, wenn ich MouseLeave erhöhen muss, wenn die Maus das ganze Fenster verlässt? Ich vermute, dass ich MouveMouve-Ereignisse nicht erhalte, wenn die Maus nicht mehr in Windows ist, damit Ihre MouseMove-basierte Lösung nicht funktioniert. Oder liege ich falsch? – SiberianGuy

+0

@ Idsa Es funktioniert auch für Formulare. – dognose

+1

Aber wir sprechen hier über WPF. Ich bezweifle, dass es für WPF-Fenster – SiberianGuy

1

Und auf Vollständigkeit und historischen Gründen (nicht die Prämie - es macht keinen Sinn, die zwei doppelte Fragen stellen - Sie sollten es wahrscheinlich in eine bewegen, wenn nicht zu spät) ...

machte ich eine gründliche Lösung global mouse hook hier (Ansatz 2)
WPF: mouse leave event doesn't trigger with mouse down

und vereinfacht den Einsatz mit - Sie können es durch die Bindung an Befehle aus Ihrer Sicht-Modell verwenden - zB

my:Hooks.EnterCommand="{Binding EnterCommand}" 
my:Hooks.LeaveCommand="{Binding LeaveCommand}" 
my:Hooks.MouseMoveCommand="{Binding MoveCommand}" 

... mehr Details gibt es in