2010-01-18 7 views
19

Ich kann ein wie diese mit einem Klick auf einen Textblock fangen:Wie kann ich sowohl Einzelklick- als auch Doppelklickereignisse in WPF FrameworkElement abfangen?

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

ich ein doppelklicken Sie auf auf einem Textblock wie diese fangen:

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

Aber wie tun Ich fange sie beide auf einem einzigen Textblock und differenziere zwischen den beiden?

+3

Wie unterscheidet der _user_ zwischen ihnen? –

Antwort

3

Wenn Sie den Unterschied erkennen müssen, empfehle ich Ihnen eine Steuerung verwenden wie Label, dass die Arbeit für Sie:

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

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

EDIT: Mein Rat wurde nach von der Dokumentation auf MSDN:

Die Steuerelementklasse definiert die PreviewMouseDoubleClick- und MouseDoubleClick-Ereignisse, jedoch nicht die entsprechenden Einzelklickereignisse. Um zu sehen, wenn der Benutzer die Steuer einmal geklickt hat, übernehmen die MouseDown- Ereignis (oder einer seiner Kollegen) und geprüft, ob die Eigenschaft Clickcount Wert ist 1.

Allerdings werden Sie so tun geben eine Einzelklickbenachrichtigung, auch wenn der Benutzer nur einmal klickt.

+0

+1 für Vorschlag Label zu verwenden, erkannte nicht, dass es geerbt von Control im Gegensatz zu TextBlock, aber tatsächlich in meiner Anwendung erhalte ich ein FrameworkElement, also brauche ich eine Lösung ohne Verwendung von Control. –

+0

"Wenn Sie dies tun, erhalten Sie jedoch eine einzige Klickbenachrichtigung, auch wenn der Benutzer nur einmal klickt." - Sie meinen, es gibt Ihnen einen einzigen Klick, selbst wenn der Benutzer * double * klickt, oder? –

+1

Dies funktioniert überhaupt nicht. Du wirst MouseDown immer noch mit einem Doppelklick erhalten und e.ClickCount wird gleich 1 sein. –

13

Sie müssen das Ereignis auslösen, nachdem die Klicksequenz vorbei ist ... wann ist das? Ich schlage vor, einen Timer zu verwenden. Das MouseDown-Ereignis würde es zurücksetzen und die Anzahl der Klicks erhöhen. Wenn das Zeitintervall verstrichen ist, wird der Aufruf zur Auswertung der Klickanzahl ausgeführt.

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; 
    } 

Prost!

+2

Danke, dass es wirklich geholfen hat zu wissen, wie andere das gelöst haben. –

+0

Also dann mache ich einen Linksklick gefolgt von einem schnellen Rechtsklick ... –

+0

@ kelton52, ich habe versucht zu zeigen, wie es funktioniert. Verwenden Sie das Ereignis "MouseLeftButtonDown" oder ein anderes, das Ihren Anforderungen entspricht. – Natxo

2

Sie müssen einen Timer verwenden, um zwischen den beiden zu unterscheiden. Fügen Sie einen Timer zu Ihrem Formular in der GUI hinzu (am einfachsten so - es wird automatisch mit der Entsorgung umgehen usw.). In meinem Beispiel heißt der Timer clickTimer.

1

Sie könnten es auf MouseUp anstelle von MouseDown tun. Auf diese Weise können Sie die Eigenschaft ClickCount nach der Gesamtzahl der Klicks fragen und entscheiden, was Sie von diesem Punkt aus tun möchten.

1

Ich habe es auf diese Weise, und es funktioniert perfekt

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

Sie sind einfach MouseDown Ereignis verwenden und die Nummer klicken zählen, wie folgt aus:

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

Viel einfacher als die anderen Antworten. – rolls

0

Es ist meine Arbeitslösung :)

#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