2009-06-09 8 views
14

Devo gestire sia il singolo clic sia il doppio clic di un pulsante in un'applicazione WPF con una reazione diversa. Sfortunatamente, su un doppio clic, WPF attiva due eventi click e un evento doppio clic, quindi è difficile gestire questa situazione.WPF: clic singolo con pulsante + doppio clic

Ha provato a risolverlo utilizzando un timer ma senza successo ... Spero che tu possa aiutarmi.

Vediamo il codice:

private void delayedBtnClick(object statInfo) 
{ 
    if (doubleClickTimer != null) 
     doubleClickTimer.Dispose(); 
    doubleClickTimer = null; 

    this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new VoidDelegate(delegate() 
    { 
     // ... DO THE SINGLE CLICK ACTION 
    })); 
} 

private void btn_Click(object sender, RoutedEventArgs e) 
{ 
    if (doubleClickTimer == null) 
     doubleClickTimer = new Timer(delayedBtnClick, null, System.Windows.Forms.SystemInformation.DoubleClickTime, Timeout.Infinite); 
     } 
    } 
} 

private void btnNext_MouseDoubleClick(object sender, MouseButtonEventArgs e) 
{ 
    if (doubleClickTimer != null) 
     doubleClickTimer.Change(Timeout.Infinite, Timeout.Infinite); // disable it - I've tried it with and without this line 
     doubleClickTimer.Dispose(); 
    doubleClickTimer = null; 

    //.... DO THE DOUBLE CLICK ACTION 
} 

Il problema è che il 'click ACTION SINGLE' chiamato dopo il 'click DOUBLE ACTION' su DoubleClick. E 'strano che ho impostato il doubleClickTimer a null il doppio click, ma nel delayedBtnClick è vero: O

ho già provato a usare il tempo più lungo, una bandiera bool e il blocco ...

Avete qualche idee?

Il migliore!

risposta

16

Se si imposta 's e.Handled a true dopo aver maneggiato l'evento MouseDoubleClick il RoutedEvent allora non chiamerà il Click evento la seconda volta dopo il MouseDoubleClick.

C'è un recent post che tocca comportamenti diversi per SingleClick e DoubleClick che possono essere utili.

Tuttavia, se si è certi di voler comportamenti separati e vogliono/necessità di bloccare la prima Click così come il secondo Click, è possibile utilizzare il DispatcherTimer come se fossi.

private static DispatcherTimer myClickWaitTimer = 
    new DispatcherTimer(
     new TimeSpan(0, 0, 0, 1), 
     DispatcherPriority.Background, 
     mouseWaitTimer_Tick, 
     Dispatcher.CurrentDispatcher); 

private void Button_MouseDoubleClick(object sender, MouseButtonEventArgs e) 
{ 
    // Stop the timer from ticking. 
    myClickWaitTimer.Stop(); 

    Trace.WriteLine("Double Click"); 
    e.Handled = true; 
} 

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    myClickWaitTimer.Start(); 
} 

private static void mouseWaitTimer_Tick(object sender, EventArgs e) 
{ 
    myClickWaitTimer.Stop(); 

    // Handle Single Click Actions 
    Trace.WriteLine("Single Click"); 
} 
+0

Grazie mille! e.Handled = true era il trucco! Grazie ancora per la rapida reazione :) – Hunsoul

+1

Se si utilizza quel costruttore per DispatcherTimer, il timer si avvia immediatamente, causando un evento spurio a singolo clic. Anche lo sfondo e la corrente sono valori predefiniti, quindi confondete un po 'le cose (pensavo che ci potesse essere del voodoo lì!). Molto utile però - evviva! –

+0

Non vedo l'utilizzo di DoubleClickTime nel codice. Invece vedo un ritardo hardcoded. È normale? – SandRock

6

Si potrebbe provare questo:

Button.MouseLeftButtonDown += Button_MouseLeftButtonDown; 

private void Button_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    e.Handled = true; 

    if (e.ClickCount > 1) 
    { 
     // Do double-click code 
    } 

    else 
    { 
     // Do single-click code 
    } 
} 

Se neccessary, si potrebbe richiedere un clic del mouse e attendere che il mouse fino a eseguire l'azione.

+0

Grazie per la risposta! Non l'ho provato perché la prima raccomandazione ha risolto il mio problema, ma grazie ancora! :) – Hunsoul

+2

Ho provato questo e funziona benissimo. Spero che questo commento sarà utile per gli altri. Grazie Josh. – akjoshi

+1

Ciò non impedirà il primo evento a clic singolo, perché per il primo evento click e.ClickCount = 1. – Knasterbax