2008-10-02 5 views
14

Próbowałem ten XAML:WPF: Suwak robi podnieść MouseLeftButtonDown lub MouseLeftButtonUp

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

a to C#:

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

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

Zmienna sliderMouseDown nigdy się nie zmienia, ponieważ wydarzenia MouseLeftButtonDown i MouseLeftButtonUp nigdy nie są podniesione. Jak mogę uruchomić ten kod, gdy użytkownik ma lewy przycisk myszy na suwaku, aby ustawić wartość bool na wartość true, a kiedy mysz jest podniesiona, wartość bool jest ustawiona na false?

Odpowiedz

14

Suwaki pochłaniają zdarzenia MouseDown (podobne do przycisku).

Można zarejestrować się w przypadku zdarzeń PreviewMouseDown i PreviewMouseUp, które zostaną wystrzelone, zanim suwak będzie miał możliwość ich obsłużenia.

+0

Dziękuję, mogłem wykorzystać zdarzenie IsMouseCapturedWithinChanged w połączeniu ze zdarzeniami PreviewMouseLeftButtonUp, aby osiągnąć mój ostateczny cel. – Nick

+0

Czy ktoś zna uzasadnienie tego zachowania? – PeterAllenWebb

+0

Powodem tego zachowania jest to, że przycisk obsługuje zdarzenie MouseDown. Domyślnie, jeśli dowolna kontrolka stwierdza, że ​​obsłużyło wydarzenie, nikt inny nie otrzyma powiadomienia, chyba że określi, że chce widzieć również zdarzenia obsługiwane. –

16

Innym sposobem, aby go lepiej (i ewentualnie w zależności od scenariusza) zrobić, to zarejestrować obsługi zdarzeń w kodzie proceduralnym jak następuje:

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

Uwaga prawdziwy argument. W zasadzie mówi, że chcesz otrzymać to wydarzenie, nawet jeśli zostało oznaczone jako obsługiwane. Niestety, podpięcie programu obsługi zdarzeń w ten sposób może być wykonane tylko z kodu proceduralnego, a nie z xaml.

Innymi słowy, za pomocą tej metody można zarejestrować obsługę zdarzeń dla normalnego zdarzenia (które bąbelki) zamiast zdarzenia podglądu, które tunele (i dlatego występują w różnych momentach).

Zobacz pasek boczny Digting Deeper na stronie 70 z WPF Unleashed, aby uzyskać więcej informacji.

+1

Korzystanie z tej sztuczki wydaje się być typem hack, który może znacznie utrudnić pracę (lub czyjąś) w przyszłości. Czy to naprawdę dobry pomysł? – PeterAllenWebb

+0

Nie nazwałbym tego hackem. Jednak, o ile to jest powiedziane, starałbym się go unikać, jeśli to możliwe, ale jeśli jesteś pomiędzy rockiem a twardym miejscem ... Pozwól mi wyjaśnić. Zdarzenia podglądu są uruchamiane przed zwykłymi zdarzeniami. Używanie podglądu zdarzeń może nie zawsze działać w danej sytuacji. – cplotts

+0

To jest "jedyny" sposób, w jaki możemy zrobić WPF pracy w naszej aplikacji MFC. Zdarzenie podglądu powoduje bałagan w przesyłaniu wiadomości w aplikacji. –

1

Chciałbym wspomnieć, że Slider nie pochłania całego zdarzenia MouseDown. Kliknięcie znacznika wyboru powoduje, że może uzyskać powiadomienie o zdarzeniu. Suwak nie obsługuje zdarzeń MouseDown, chyba że pochodzą one z suwaka ... suwaka.

Zasadniczo, jeśli zdecydujesz się korzystać z wersji

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

z kleszcze włączone, mieć pewność, że zdarzenie zostało obsługiwane wcześniej. Jeśli tego nie zrobisz, skończysz z przypadkiem, w którym myślałeś, że suwak został kliknięty, ale to był naprawdę tyknięcie. Rejestracja na podglądzie jest jeszcze gorsza - będziesz odbierać wydarzenia w dowolnym miejscu, nawet na białej przestrzeni między kleszczami.

4

Spróbuj użyć funkcji LostMouseCapture i GotMouseCapture.

private void sliderr_LostMouseCapture(object sender, MouseEventArgs e) 

    private void slider_GotMouseCapture(object sender, MouseEventArgs e) 

GotMouseCapture pożary, gdy użytkownik zaczyna przeciągając suwak i LostMouseCapture kiedy uwalnia go.