2010-01-18 4 views
19

je peux attraper un seul clic sur un TextBlock comme ceci:Comment est-ce que je peux attraper les événements de simple-clic et de double-clic sur WPF FrameworkElement?

private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e) 
{ 
    MessageBox.Show("you single-clicked"); 
} 

je peux attraper un double-clic sur un TextBlock comme ceci:

private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e) 
{ 
    if (e.LeftButton == MouseButtonState.Pressed) 
    { 
     if (e.ClickCount == 2) 
     { 
      MessageBox.Show("you double-clicked"); 
     } 
    } 
} 

Mais comment Je les attrape tous les deux sur un seul TextBlock et différencie les deux?

+3

Comment l'utilisateur se différenciera-t-il? –

Répondre

3

Si vous devez détecter la différence, je vous suggère d'utiliser un contrôle tel que Label qui fait le travail pour vous:

label.MouseDown += delegate(object sender, MouseEventArgs e) 
{ 
    if (e.ClickCount == 1) 
    { 
     // single click 
    } 
}; 

label.MouseDoubleClick += delegate 
{ 
    // double click 
}; 

EDIT: Mon conseil est à la suite de la documentation sur MSDN:

La classe Control définit les événements MouseDoubleClick PreviewMouseDoubleClick et , mais pas événements de simple clic correspondants. Pour voir si l'utilisateur a cliqué sur le fois le contrôle , gérer l'événement MouseDown (ou l'un de ses homologues) et vérifier si la propriété ClickCount valeur est 1.

Cependant, cela vous donnera une seule notification de clic même si l'utilisateur clique seul.

+0

+1 pour suggestion d'utiliser label, ne s'est pas rendu compte qu'il a hérité de Control contrairement à TextBlock, mais en fait, dans mon application, je reçois un FrameworkElement, j'ai donc besoin d'une solution sans utiliser Control. –

+0

"Cependant, cela vous donnera une seule notification de clic, même si l'utilisateur clique seul." - vous voulez dire qu'il vous donne un seul clic même si l'utilisateur * double * clique, non? –

+1

Cela ne fonctionne pas du tout. Vous aurez toujours MouseDown sur un double clic et e.ClickCount sera égal à 1. –

13

Vous devez déclencher l'événement après la fin de la séquence de clics ... quand est-ce? Je suggère d'utiliser une minuterie. L'événement MouseDown le réinitialiserait et augmenterait le nombre de clics. Lorsque l'intervalle de temporisation s'écoule, il appelle pour évaluer le nombre de clics.

private System.Timers.Timer ClickTimer; 
    private int ClickCounter; 

    public MyView() 
    { 
     ClickTimer = new Timer(300); 
     ClickTimer.Elapsed += new ElapsedEventHandler(EvaluateClicks); 
     InitializeComponent(); 
    } 

    private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e) 
    { 
     ClickTimer.Stop(); 
     ClickCounter++; 
     ClickTimer.Start(); 
    } 

    private void EvaluateClicks(object source, ElapsedEventArgs e) 
    { 
     ClickTimer.Stop(); 
     // Evaluate ClickCounter here 
     ClickCounter = 0; 
    } 

Cheers!

+2

Merci, il a vraiment aidé à savoir comment les autres ont résolu cela. –

+0

Alors, je fais un clic gauche suivi d'un clic droit rapide ... –

+0

@ kelton52, j'ai essayé de montrer comment cela fonctionne. Utilisez l'événement 'MouseLeftButtonDown' ou tout autre qui correspond à vos besoins. – Natxo

2

Vous devez utiliser une minuterie pour différencier les deux. Ajouter une minuterie à votre formulaire dans l'interface graphique (plus facile de cette façon - il va gérer automatiquement la disposition etc ...). Dans mon exemple, le temporisateur est appelé clickTimer.

private bool mSingleClick; 

private void TextBlock_MouseUp(object sender, MouseButtonEventArgs e) 
{ 

    if (e.Button == MouseButtons.Left) 
    { 
     if (e.ClickCount < 2) 
     { 
      mSingleClick = true; 
      clickTimer.Interval = System.Windows.Forms.SystemInformation.DoubleClickTime; 
      clickTimer.Start(); 
     } 
     else if (e.ClickCount == 2) 
     { 
      clickTimer.Stop(); 
      mSingleClick = false; 
      MessageBox.Show("you double-clicked"); 
     } 
    } 
} 

private void clickTimer_Tick(object sender, EventArgs e) 
{ 
    if (mSingleClick) 
    { 
     clickTimer.Stop(); 
     mSingleClick = false; 
     MessageBox.Show("you single-clicked"); 
    } 
} 
1

Vous pouvez le faire sur MouseUp au lieu de MouseDown. De cette façon, vous pouvez demander à la propriété ClickCount le nombre total de clics et décider quoi faire à partir de ce point.

1

Je l'ai fait de cette façon et il fonctionne parfaitement

If e.Clicks = 2 Then 
      doubleClickTimer.Stop() 
     ElseIf e.Clicks = 1 Then 
      doubleClickTimer.Enabled = True 
      doubleClickTimer.Interval = 1000 
      doubleClickTimer.Start() 


     End If 


Private Sub doubleClickTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles doubleClickTimer.Tick 

     OpenWebPage("abc") 
     doubleClickTimer.Stop() 
    End Sub 
2

Vous êtes simplement pouvez utiliser l'événement MouseDown et compter cliquez sur le numéro, comme ceci:

if (e.ChangedButton == MouseButton.Left && e.ClickCount == 2) 
{ 
    // your code here 
} 
+1

Beaucoup plus simple que les autres réponses. – rolls

0

C'est ma solution de travail :)

#region message label click -------------------------------------------------------------------------- 
private Timer messageLabelClickTimer = null; 

private void messageLabel_MouseUp(object sender, MouseButtonEventArgs e) 
{ 
    Debug.Print(e.ChangedButton.ToString() + "/Left:" + e.LeftButton.ToString() + " Right:" + e.RightButton.ToString() + " click: " + e.ClickCount.ToString()); 
    // in MouseUp (e.ClickCount == 2) don't work!! Always 1 comes. 
    // in MouseDown is set e.ClickCount succesfully (but I don't know should I fire one clicked event or wait second click) 

    if (e.ChangedButton == MouseButton.Left) 
    { 
    if (messageLabelClickTimer == null) 
    { 
     messageLabelClickTimer = new Timer(); 
     messageLabelClickTimer.Interval = 300; 
     messageLabelClickTimer.Elapsed += new ElapsedEventHandler(messageLabelClickTimer_Tick); 
    } 

    if (! messageLabelClickTimer.Enabled)             
    { // Equal: (e.ClickCount == 1) 
     messageLabelClickTimer.Start(); 
    } 
    else 
    { // Equal: (e.ClickCount == 2) 
     messageLabelClickTimer.Stop(); 

     var player = new SoundPlayer(ExtraResource.bip_3short);    // Double clicked signal 
     player.Play(); 
    } 
    } 
} 

private void messageLabelClickTimer_Tick(object sender, EventArgs e) 
{ // single-clicked 
    messageLabelClickTimer.Stop(); 

    var player = new SoundPlayer(ExtraResource.bip_1short);     // Single clicked signal 
    player.Play(); 
}  
#endregion 
Questions connexes