1

可以使用 MouseRightButtonDown 事件检测触摸按住手势。不幸的是,直到我从屏幕上松开手指,它才会触发。这太晚了!

有人有想法吗?提前致谢。

4

5 回答 5

5

有可能以一种等待的方式做到这一点。创建具有特定间隔的计时器。当用户点击时启动它,并在计时器结束时返回该方法。如果用户松开手,则返回带有 false 标志的方法。

public static Task<bool> TouchHold(this FrameworkElement element, TimeSpan duration)
{
    DispatcherTimer timer = new DispatcherTimer();
    TaskCompletionSource<bool> task = new TaskCompletionSource<bool>();
    timer.Interval = duration;

    MouseButtonEventHandler touchUpHandler = delegate
    {
        timer.Stop();
        if (task.Task.Status == TaskStatus.Running)
        {
            task.SetResult(false);
        }
    };

    element.PreviewMouseUp += touchUpHandler;

    timer.Tick += delegate
    {
        element.PreviewMouseUp -= touchUpHandler;
        timer.Stop();
        task.SetResult(true);
    };

    timer.Start();
    return task.Task;
}

欲了解更多信息,请阅读这篇文章

于 2014-08-07T06:31:28.320 回答
2

很棒的一段代码。为了完整性,我只添加了一个示例用法:

private async void btn_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
  if (await TouchHold(btn, TimeSpan.FromSeconds(2)))
  {
    // todo: long press code goes here
  }
}

并来自 XAML:

<Button Name="btn" PreviewMouseDown="btn_PreviewMouseDown">Press long</Button>
于 2017-05-24T22:23:39.553 回答
1

使用Blake.NUI 工具包提供的 Hold 手势

于 2013-03-05T21:24:03.327 回答
0

无论是按钮、标签还是图像,我们都可以使用MouseDownandMouseUp来启动延迟和停止延迟。

对于MouseDown,

    // Declaration of timer and timercount
     int timerCount = 0;
     DispatcherTimer dt = new DispatcherTimer();

     public myConstructor()
            {
                dt.Interval = new TimeSpan(0, 0, 1);
            }

    // Mouse Down Event
     private void EnterHoldState(object sender, TouchEventArgs e)
            {
                timerStarted();
            }

    //Mouse Up event
        private void ExitHoldState(object sender, RoutedEventArgs e)
                {
                    timerStopped();
                }

// Stops the timer and resets the timer count to 0
        private void timerStopped()
        {
            dt.Stop();
            timerCount = 0;
        }

// Starts the timer and sets delayCounter function for counting the delay seconds and acts on it
        private void timerStarted()
        {
            dt.Tick += delayCounter;
            dt.Start();
            
        }

//Once delay timer reaches 2 seconds, the button navigates to nextpage.
        private void delayCounter(object sender, EventArgs e)
        {
            timerCount++;
            if (timerCount == 2)
            {
                this.NavigationService.Navigate(new nextPage());
            }
        }
于 2020-07-22T14:16:12.673 回答
0

我最近不得不实现一个Button我需要在按下五秒钟后触发的地方。

为此,我创建了一个附加行为。我有五秒钟的时间来恢复行为,因为我不需要这个可配置的但很容易用 a 完成,Dependency Property并且它被连接起来以Command某种MVVM方式与 a 一起使用,但它可以很容易地更改为 trigger Click

    <Button Command="{Binding Path=ButtonCommand}">
        <i:Interaction.Behaviors>
            <behaviors:PressAndHoldBehavior />
        </i:Interaction.Behaviors>
    </Button>

public sealed class PressAndHoldBehavior : Behavior<Button>
{
    private DispatcherTimer dispatcherTimer;

    protected override void OnAttached()
    {
        dispatcherTimer = new DispatcherTimer {Interval = TimeSpan.FromSeconds(5)};
        dispatcherTimer.Tick += OnDispatcherTimerTick;
        AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObjectPreviewMouseLeftButtonDown;
        AssociatedObject.PreviewMouseLeftButtonUp += AssociatedObjectPreviewMouseLeftButtonUp;
    }

    protected override void OnDetaching()
    {
        dispatcherTimer.Stop();
        dispatcherTimer.Tick -= OnDispatcherTimerTick;
        dispatcherTimer = null;
        AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObjectPreviewMouseLeftButtonDown;
        AssociatedObject.PreviewMouseLeftButtonUp -= AssociatedObjectPreviewMouseLeftButtonUp;
    }

    private void AssociatedObjectPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        dispatcherTimer.Start();
        e.Handled = true;
    }

    private void AssociatedObjectPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        dispatcherTimer.Stop();
        e.Handled = true;
    }

    private void OnDispatcherTimerTick(object sender, EventArgs e)
    {
        AssociatedObject.Command.Execute(null);
    }
}
于 2021-07-28T13:34:27.853 回答