【问题标题】:how to avoid click when I want double click?当我想双击时如何避免点击?
【发布时间】:2013-08-22 09:07:23
【问题描述】:

我在 WPF 中有一个应用程序和一个按钮。在这个按钮中,我想要实现代码的单击事件,但是我希望当用鼠标双击时,执行其他代码而不是单击事件的代码。

问题是click事件的代码总是被执行,不知道有没有办法避免doulbe click的时候执行click事件。

我遵循 MVVM 模式,我使用 MVVM 灯将事件转换为命令。

谢谢。

【问题讨论】:

  • 你的按钮没有OnMouseDoubleClick事件吗?
  • 是的,我的按钮有两个事件,点击事件和鼠标双击事件。
  • 那么为什么不在OnMouseDoubleClick 事件中编写你想要执行的代码呢?
  • 因为我想要两个不同的代码。如果用户单击一次,则一个代码,如果用户双击,则另一个用户。我需要区分用户何时执行一项或另一项操作。
  • 查看我的答案中的链接。它向您展示了如何区分正常单击和双击。在此基础上,您可以在单击和双击中使用所需的任何代码。

标签: c# events wpf-controls mvvm-light


【解决方案1】:

在点击事件上,可以查看EventArgs中的点击量,例如;

private void RightClickDown(object sender, MouseButtonEventArgs e)
    {
        if (e.ClickCount == 1)
        {
            //do single click work here.
        }
        if (e.ClickCount == 2)
        {
            //do double click work.
        }
    }

这意味着您可以手动区分单击和双击,如果您愿意的话。

【讨论】:

  • 我试过这种方式。问题是,如果我想要触发事件,我需要使用 MouseLeftDown 的 PreviewMouseLeftDown 事件,所以我认为如果我使用预览事件,则此代码不起作用。如果我使用 MouseLeftDown 事件不会被触发。
  • 这里有检测到双击的问题,但是首先总是检测到第一次点击,所以一直执行单击的代码。稍后如果有第二次点击,则执行双击的代码。
【解决方案2】:

在处理完 MouseDoubleClick 事件后将 RoutedEvent 的 e.Handled 设置为 True 以阻止第二次点击事件被触发。

如果要阻止首次点击事件行为,可以使用计时器:

private static DispatcherTimer myClickWaitTimer = 
    new DispatcherTimer(
        new TimeSpan(0, 0, 0, 0, 250), 
        DispatcherPriority.Normal, 
        mouseWaitTimer_Tick, 
        Dispatcher.CurrentDispatcher) { IsEnabled = false };

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

【讨论】:

  • 但这不会触发第一次点击事件?因为我认为问题在于,当我第一次单击双击时,单击事件会触发,因为应用程序不知道我是否要双击。
  • 在我实例化调度程序时使用此解决方案,调度程序正在运行,因此在我实例化我的视图模型时执行。有没有办法将调度程序实例化为停止状态?
  • 如果我在视图模型的构造函数中创建调度程序,而不是在变量类的声明中创建调度程序,并且我立即停止调度程序不会在创建视图模型时执行。
  • 我有问题。调度器如何是静态的,我只能使用静态变量,但我需要使用视图模型的其他非静态属性。如果我将调度程序设置为非静态,则调度程序不会停止。
【解决方案3】:

Here 很好地解释了如何区分单击和双击。它为您提供了 2 个示例,说明如何实现这一目标。

【讨论】:

    【解决方案4】:

    我分享了这个解决方案,它混合了其他两个解决方案。抱歉,我无法为两者都提供公认的解决方案。

    如果我使用 PreviewMouseLeftButtonDown 来控制单击或双击何时起作用,而不是使用两个事件(单击和双击)。

    所以我用这段代码解决了问题:

    第一种方法控制鼠标点击。

    private void MouseLeftButtonDownCommand(MouseButtonEventArgs e)
            {
    
                if (e.ClickCount == 1)
                {
                    _dtMouseClick.Start();
                }
    
                else if(e.ClickCount > 1)
                {
                    _dtMouseClick.Stop();
    
                    //the code of the double click
                }
            }
    

    这个方法是链接到DispatcherTimer的方法,如果鼠标第二次点击没有停止则执行。

    private void MouseClick_Tick(object sender, System.EventArgs e)
            {
                _dtrMouseClick.Stop();
    
                //code of the single click                
            }
    

    dispatcherTimer 在视图模型的构造函数中创建

    _dtBotonBuscarMouseClick =
                    new System.Windows.Threading.DispatcherTimer(
                    new TimeSpan(0, 0, 0, 0, 250),
                    System.Windows.Threading.DispatcherPriority.Background,
                    MouseClick_Tick,
                    System.Windows.Threading.Dispatcher.CurrentDispatcher);
                _dtMouseClick.Stop();
    

    间隔为 250ms,即用户必须双击的时间间隔。

    在这个解决方案中,我使用相同的方法来停止 dispatcherTimer,即 stop() 方法,但是由于某种原因,如果我使用两个事件(单击和 mouseDoubleClick),则 dispatcherTimer 不会在双击时停止,如果我使用解决方案工作的 MouseLeftButtonDown 事件。

    【讨论】:

      猜你喜欢
      • 2012-04-07
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      • 1970-01-01
      • 2016-04-02
      • 2012-10-17
      • 2017-09-10
      • 1970-01-01
      相关资源
      最近更新 更多