如何在WPF FrameworkElement上捕获单击和双击事件?

时间:2010-01-18 13:16:22

标签: c# wpf event-handling double-click

我可以在TextBlock上捕获单击,如下所示:

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

我可以在TextBlock上捕获双击,如下所示:

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

但是如何在单个TextBlock上捕获它们并区分它们?

9 个答案:

答案 0 :(得分:13)

您需要在点击序列结束后触发事件......这是什么时候?我建议使用计时器。 MouseDown事件会重置它并增加点击次数。当计时器间隔过去时,它会进行调用以评估点击次数。

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

干杯!

答案 1 :(得分:3)

如果您需要检测差异,我建议您使用Label这样的控件为您完成工作:

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

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

编辑:我的建议是关于MSDN的文档:

  

Control类定义了   PreviewMouseDoubleClick和   MouseDoubleClick事件,但不是   相应的单击事件。至   看用户是否点击了   控制一次,处理MouseDown   事件(或其中一个对应物)和   检查ClickCount属性   值是1。

但是,即使用户单击,这样做也会为您提供单击通知。

答案 2 :(得分:2)

您必须使用计时器来区分这两者。在GUI中为表单添加一个计时器(最简单的方法 - 它将自动处理处理等...)。在我的示例中,计时器名为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");
    }
}

答案 3 :(得分:2)

您只需使用MouseDown事件并计算点击次数,如下所示:

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

答案 4 :(得分:1)

您可以在MouseUp而不是MouseDown上执行此操作。这样,您可以向ClickCount属性询问总点击次数,并决定从该点开始做什么。

答案 5 :(得分:1)

我这样做了,它完美无缺

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

答案 6 :(得分:1)

我的建议,只需使用UserControlTask中实现:

private int _clickCount = 0;
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
    _clickCount = e.ClickCount;
}

protected override async void OnPreviewMouseUp(MouseButtonEventArgs e)
{
    if (_clickCount > 1)
    {
        //apparently a second mouse down event has fired => this must be the second mouse up event
        //no need to start another task
        //the first mouse up event will be handled after the task below
        return; 
    }

    await Task.Delay(500);

    if (_clickCount == 1)
    {
        //single click
    }
    else
    {
        //double (or more) click
    }
}

当然,所有这些解决方案的缺点是,在实际响应用户的操作之前会有一个延迟。

答案 7 :(得分:0)

这是我的工作解决方案:)

    #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

答案 8 :(得分:0)

我的问题是在DataGrid的{​​{1}}中单击/双击行。由于某些原因,WPF事件没有触发,只有ButtonDown事件触发。无论如何,我要以不同于双击的方式处理单击。我花了一点时间(我确定解决方案不是完美的,但似乎可行)将问题归结为问题,直到我将问题归结为下。我创建了一个称为OnMouseLeftButtonUp的{​​{1}},并且可以通过第二次单击来更新Task的目标。希望这对某人有帮助!

Action