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

问题描述 投票:20回答:8

我可以像这样在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上同时捕获它们并区分两者?

c# wpf event-handling double-click
8个回答
12
投票

您需要在点击顺序结束后才触发事件……那是什么时候?我建议使用计时器。 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;
    }

干杯!


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
投票

您必须使用计时器来区分两者。在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");
    }
}

2
投票

您完全可以使用MouseDown事件并计算点击次数,例如:

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

1
投票

您可以在MouseUp而不是MouseDown上进行操作。这样,您可以向ClickCount属性询问总的点击次数,然后决定从那一点开始要做的事情。


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

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

0
投票

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

private Action _clickAction;
private int _clickCount;

private void Grid_OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    Debug.WriteLine("Button Click Occurred");

    _clickCount++;

    if (_clickCount == 1)
    {
        _clickAction = SingleClick;
    }

    if (_clickCount > 1)
    {
        _clickAction = DoubleClick;
    }

    if (_clickCount == 1)
    {
        Task.Delay(200)
            .ContinueWith(t => _clickAction(), TaskScheduler.FromCurrentSynchronizationContext())
            .ContinueWith(t => { _clickCount = 0; });
    }
}

private void DoubleGridClick()
{
    Debug.WriteLine("Double Click");
}

private void SingleGridClick()
{
    Debug.WriteLine("Single Click");
}
© www.soinside.com 2019 - 2024. All rights reserved.