【问题标题】:How can I get repeated double-clicks without WPF changing some to triple-clicks?如何在不将 WPF 更改为三次单击的情况下重复双击?
【发布时间】:2011-04-23 09:40:40
【问题描述】:

我的 WPF 应用程序中有一个列表框,当用户双击某个项目时,我会更改列表的内容(类似于目录导航)。在某些情况下,双击然后立即再次双击是有意义的,因为您知道在同一位置会出现什么。你会认为你可以通过快速连续点击四次来做到这一点(这应该意味着“两次双击”)。

但这不起作用。如果您单击足够快速,直到第五次或第六次单击 WPF 才会发送另一个双击事件!

看起来 WPF 内置了对三次单击的支持,如果单击速度足够快,有时甚至更多。我跑了一个简单的例子来确认这一点:

<ListBox PreviewMouseLeftButtonDown="ListBox_PreviewMouseLeftButtonDown"/>

private void ListBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Trace.WriteLine("ClickCount = " + e.ClickCount);
}

当我运行它并点击快速射击时,我得到如下输出:

ClickCount = 1
ClickCount = 2
ClickCount = 3
ClickCount = 1
ClickCount = 2
ClickCount = 3
ClickCount = 4
ClickCount = 1
ClickCount = 2
ClickCount = 3

有时它会数到 3 然后重新设置;有时它会在重置之前数到 4。我无法让它上​​升到 5。

但后来我进入控制面板 > 鼠标,并将我的双击速度更改为最慢的设置。然后我能够可靠地让它在重置之前数到 10,如果我真的预订它,最多可以数到 11 或 12。因此,显然这完全取决于您在系统配置的“双击”间隔之前可以单击多快。如果您在该间隔结束之前单击更多次,您将获得“三次单击”或“四次单击”或更多。

但我不想要三次点击或四次点击——尤其是在某些双击配置无法实现的情况下。我希望所有其他单击都是双击事件(只要它们快速连续,鼠标移动不超过阈值等)

当我点击快速触发时,有什么方法可以让 WPF 为我提供正常的双击事件(每隔一次点击的事件)?

【问题讨论】:

  • 既然你已经成功统计了点击次数,何不在ClickCount % 2 == 0时做任何你需要做的事情?
  • @madd0,再看看我发布的输出。 ClickCount 不会继续增加。鉴于上面的示例输出,您将响应第 2 次、第 5 次、第 7 次和第 10 次点击。偶尔它会得到想要的行为,但只是偶然。

标签: wpf double-click


【解决方案1】:

使用几个实例变量:_LastMouseDownTime 和 _LastMouseDownWasDoubleClick:

    private int _LastMouseDownTime;
    private bool _LastMouseDownWasDoubleClick;

    private void ListBox_PreviewMouseDown(object sender, MouseButtonEventArgs e) {
        if(e.Timestamp - _LastMouseDownTime <= System.Windows.Forms.SystemInformation.DoubleClickTime && !_LastMouseDownWasDoubleClick) {
            Debug.Print("DoubleClick - StupidWorthlessClickCount:{0}", e.ClickCount);
            _LastMouseDownWasDoubleClick = true;

            //Do some double clicking goodness
        } else {
            Debug.Print("FirstClick - StupidWorthlessClickCount:{0}", e.ClickCount);
            _LastMouseDownWasDoubleClick = false;

            //Do some single clicking goodness
        }
        _LastMouseDownTime = e.Timestamp;
        base.OnMouseDown(e);
    }

我知道这是超级 hacky 并且不是很灵活,但它应该可以满足您的需求。我试图让 WPF RichTextBox 响应那些第 4 次、第 5 次等点击,就像它们是第 1 次、第 2 次等一样,以使选择工作更自然,但这可能被证明是不可能的! :)

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    ClickCount 显示用户在系统双击时间内点击了多少次。因此,如果您只需要双击响应:

    private void ListBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (e.ClickCount % 2 == 1)
            return;
        Trace.WriteLine(e.ClickCount + " " + DateTime.Now);
    }
    

    输出:

    //2 clicks:
    2 10.03.2011 16:05:17
    //4 clicks:
    2 10.03.2011 16:05:20
    4 10.03.2011 16:05:20
    //3 clicks:
    2 10.03.2011 16:05:26
    

    【讨论】:

    • 您的第一句话准确地解释了为什么您的代码不起作用。 再看看我发布的示例输出,ClickCount 实际返回的内容。您的代码将响应第 2 次、第 5 次、第 7 次和第 10 次点击。我想要能够响应第 2 次、第 4 次、第 6 次、第 8 次和第 10 次点击的内容。
    • ClickCount % 2 == 1 将在第一次点击时为真,而不是在第二次点击时——所以,不。再次,阅读您自己答案的第一句话,看看为什么这不起作用。迟早,在系统双击时间内你只会得到 3 次点击,然后 ClickCount 将不再在奇数和偶数之间进行严格的交替(它将是 1、2、3、1)。据我所知,任何依赖 ClickCount 的东西都注定要失败。
    • @Joe White,我已经看到了我发布的内容的输出。当某人只点击一次时,什么都不会发生; 1 次双击 - 1 次代码执行;三击将给出与双击相同的行为(如第三次单击对用户来说是错误的)、4 次单击 - 2 次执行、5 - 2、6 - 3 等等。根据您的 ,双击然后立即再次双击是有意义的,因为您知道在同一位置会出现什么。你会认为你可以通过快速连续点击四次来做到这一点(这应该意味着“两次双击”)。这段代码给出了一个解决方案。
    • 当我说% 2 错误时,我完全倒着阅读你的代码——我很抱歉。但是您假设只要您继续单击,ClickCount 就会不断增加,但事实并非如此。在您的双击时间过去后,它会重置为 1。如果您单击速度较慢,或更改系统的双击速度,您将达到一个点,即您(至少偶尔)在双击时间内获得奇数次点击,然后,正如我已经说过,ClickCount 将不再是奇偶之间的严格交替,这段代码会给出错误的结果。
    猜你喜欢
    • 1970-01-01
    • 2023-04-10
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 2016-07-23
    • 1970-01-01
    相关资源
    最近更新 更多