WPF DispatcherTimer和鼠标按钮点击时间

3
考虑以下代码,我有一个文本块,在WPF中它是一个“开/关”按钮。它只是一个椭圆形内部的文字,上面写着ON / OFF。当用户单击按钮并按住左键一秒钟时,如果设备尚未启动,则会执行“打开设备”的代码。如果用户按住ON / OFF按钮三秒或更长时间(保持左鼠标按钮按下),则设备将关闭。
我遇到了几个问题: 1.即使定时器已启动,当鼠标按钮按下时,计时事件也不会触发。 2.do / while循环永远不会退出,即使放开按钮。
谢谢!
    public int TimerCount = 0;

    private void ButtonPressTimer(object sender, EventArgs e)
    {
        TimerCount = TimerCount + 1;
    }

    private void txtBlockOnOff_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var buttonPressTimer = new DispatcherTimer(new TimeSpan(0, 0, 0, 1), DispatcherPriority.Normal, ButtonPressTimer, this.Dispatcher);

        do
        {
            if (!buttonPressTimer.IsEnabled)
                buttonPressTimer.Start();
        }
        while (e.ButtonState == MouseButtonState.Pressed);

        buttonPressTimer.Stop();
        if (TimerCount >= 3)
        {
            //do something here
        }
        else
        { 
            //do something different here
        }
    }
3个回答

5

我建议采用稍微不同的方法,无需设置定时器即可完成。如果您处理鼠标按下和松开事件,并存储按钮按下时的时间,那么可以将其与鼠标释放时的时间进行比较,然后决定要执行什么操作。

private DateTime mousePressed;

private void txtBlockOnOff_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    mousePressed = DateTime.Now;
}

private void txtBlockOnOff_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    // button released

    TimeSpan difference = DateTime.Now - mousePressed;

    if (difference.TotalSeconds >= 3)
    {
        // long press
    }
    else
    {
        // short press
    }
}

顺便提一下,您的要求说短按是1秒,长按是3秒,但这并不反映在代码中。与您的原始要求一样,我的示例假定长按是超过3秒的任何时间,而短按则是少于3秒的任何时间。使用我发布的代码可以轻松更改此设置,因为您可以根据需要对TimeSpan进行比较。 - Jason Anderson

3

我相信这个问题的答案是使用RepeatButton,它恰好符合你需要的要求,即一直触发事件,直到你松开按钮。


1

你被卡在循环中了 - 调度计时器在同一线程上触发,但你却被卡在了 Clicked 处理程序中。

编辑:想一想 - 任何人如何更改 MousePressed 标志?只有一个线程(技术上是两个,但记住它是一个!)如果你在处理程序中阻塞,WPF 就无法做任何事情


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接