2008-10-02 18 views
14

ich diesen XAML versucht:WPF: Slider tut erhöhen Mouseleftbuttondown oder MouseLeftButtonUp

<Slider Width="250" Height="25" Minimum="0" Maximum="1" MouseLeftButtonDown="slider_MouseLeftButtonDown" MouseLeftButtonUp="slider_MouseLeftButtonUp" /> 

Und dieses C#:

private void slider_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
sliderMouseDown = true; 
} 

private void slider_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
{ 
sliderMouseDown = false; 
} 

Die sliderMouseDown Variable ändert sich nie, weil die Mouseleftbuttondown und MouseLeftButtonUp Ereignisse nie ausgelöst werden. Wie kann ich diesen Code zum Laufen bringen, wenn ein Benutzer die linke Maustaste auf einem Schieberegler hat, um einen bool-Wert auf wahr zu setzen, und wenn die Maus oben ist, wird der bool auf false gesetzt?

Antwort

14

Schieberegler schlucken die MouseDown Events (ähnlich wie die Schaltfläche).

Sie können sich für die PreviewMouseDown- und PreviewMouseUp-Ereignisse registrieren, die ausgelöst werden, bevor der Slider die Möglichkeit hat, mit ihnen umzugehen.

+0

Vielen Dank, ich konnte das IsMouseCapturedWithinChanged-Ereignis in Kombination mit den PreviewMouseLeftButtonUp-Ereignissen verwenden, um mein endgültiges Ziel zu erreichen. – Nick

+0

Kennt jemand die Gründe für dieses Verhalten? – PeterAllenWebb

+0

Der Grund für dieses Verhalten ist, dass die Schaltfläche das MouseDown-Ereignis behandelt. Wenn ein Steuerelement angibt, dass es ein Ereignis behandelt hat, wird standardmäßig niemand benachrichtigt, es sei denn, sie haben angegeben, dass auch behandelte Ereignisse angezeigt werden sollen. –

16

Ein anderer Weg, es (und möglicherweise besser je nach Szenario) zu tun ist, um einen Ereignishandler in prozeduralen Code wie folgt zu registrieren:

this.AddHandler 
(
    Slider.MouseLeftButtonDownEvent, 
    new MouseButtonEventHandler(slider_MouseLeftButtonDown), 
    true 
); 

Bitte das wahre Argument beachten. Es besagt grundsätzlich, dass Sie dieses Ereignis erhalten möchten, selbst wenn es als behandelt markiert wurde. Leider kann ein solcher Event-Handler nur aus prozeduralem Code und nicht aus xaml heraus aufgerufen werden.

Mit dieser Methode können Sie einen Ereignishandler für das normale Ereignis (die Blasen) anstelle des Vorschauereignisses registrieren, das tunnelt (und daher zu unterschiedlichen Zeiten auftritt).

Weitere Informationen finden Sie im Abschnitt "Digging Deeper sidebar" auf Seite 70 von WPF Unleashed.

+1

Mit diesem Trick scheint die Art von Hack, die Ihre Arbeit (oder jemand anderes) in der Zukunft viel schwieriger machen könnte. Ist das wirklich eine gute Idee? – PeterAllenWebb

+0

Ich würde es nicht als Hack bezeichnen. Allerdings würde ich versuchen, es zu vermeiden, wenn es möglich ist, aber wenn Sie zwischen Stein und einem harten Platz sind ... Lassen Sie mich erklären. Die Vorschau-Ereignisse werden vor den regulären Ereignissen ausgelöst. Daher funktioniert die Verwendung der Vorschau-Ereignisse möglicherweise nicht immer in der vorliegenden Situation. – cplotts

+0

Es ist der "einzige" Weg, wie wir WPF innerhalb unserer MFC-Anwendung arbeiten lassen können. Die Vorschauereignisse sind mit unserem Messaging innerhalb der Anwendung vermischt. –

1

Ich möchte erwähnen, dass der Slider das gesamte MouseDown Event nicht ganz schluckt. Durch Klicken auf ein Häkchen können Sie für das Ereignis benachrichtigt werden. Der Slider wird keine MouseDown-Ereignisse behandeln, es sei denn, sie stammen vom Schieberegler des Schiebereglers.

Grundsätzlich, wenn Sie die

AddHandler(Slider.MouseLeftButtonDownEvent, ..., true) 

Version zu verwenden entscheiden, mit den Zecken eingeschaltet, stellen Sie sicher, dass das Ereignis zuvor behandelt wurde. Wenn Sie das nicht tun, werden Sie mit einem Randfall enden, bei dem Sie dachten, dass der Schieberegler angeklickt wurde, aber es war wirklich ein Tick. Die Registrierung für das Preview-Event ist noch schlimmer - Sie werden das Event überall mitnehmen, sogar auf dem weißen Feld zwischen den Ticks.

4

Versuchen Sie, LostMouseCapture und GotMouseCapture zu verwenden.

private void sliderr_LostMouseCapture(object sender, MouseEventArgs e) 

    private void slider_GotMouseCapture(object sender, MouseEventArgs e) 

GotMouseCapture wird ausgelöst, wenn der Benutzer beginnt, den Schieber ziehen, und Lost, wenn er sie freigibt.