WPF按钮长按延迟触发命令实现方案(支持XAML配置时长)
WPF实现长按触发命令的延迟按钮
WPF默认按钮点击会立即触发绑定的命令,为避免误触操作,我们可以实现一个自定义按钮,要求长按达到指定时长(如500毫秒或1秒)后才触发命令,同时支持在XAML中直接配置延迟时长。
感谢BionicCode的思路启发,经过修改后实现了可用的自定义控件,代码如下:
public class DelayButton : Button { /// <summary> /// 延迟时长(毫秒) /// </summary> public int DelayInMilliseconds { get => (int)GetValue(DelayInMillisecondsProperty); set => SetValue(DelayInMillisecondsProperty, value); } public static readonly DependencyProperty DelayInMillisecondsProperty = DependencyProperty.Register( nameof(DelayInMilliseconds), typeof(int), typeof(DelayButton), new PropertyMetadata(0)); /// <summary> /// 延迟触发命令 /// </summary> public ICommand DelayCommand { get { return (ICommand)GetValue(DelayCommandProperty); } set { SetValue(DelayCommandProperty, value); } } public static readonly DependencyProperty DelayCommandProperty = DependencyProperty.Register("DelayCommand", typeof(ICommand), typeof(DelayButton), new PropertyMetadata(null)); /// <summary> /// 取消令牌源 /// </summary> private CancellationTokenSource? delayCancellationTokenSource; /// <summary> /// 触发有效性标记 /// </summary> private bool isClickValid = false; /// <summary> /// 鼠标按下事件 /// </summary> /// <param name="e"></param> protected override async void OnMouseLeftButtonDown(MouseButtonEventArgs e) { if (DelayInMilliseconds <= 0) { // 无延迟,立即触发 this.isClickValid = true; DelayCommand?.Execute(this); return; } try { this.delayCancellationTokenSource = new CancellationTokenSource(); await Task.Delay(TimeSpan.FromMilliseconds(this.DelayInMilliseconds), this.delayCancellationTokenSource.Token); // 检查鼠标仍处于按下状态且未触发过命令 if (e.LeftButton is MouseButtonState.Pressed && !this.isClickValid) { this.isClickValid = true; DelayCommand?.Execute(this); } } catch (OperationCanceledException) { return; } finally { this.delayCancellationTokenSource?.Dispose(); this.delayCancellationTokenSource = null; } } /// <summary> /// 鼠标抬起事件 /// </summary> /// <param name="e"></param> protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) { if (!this.isClickValid) { // 时长未达标,取消延迟任务 this.delayCancellationTokenSource?.Cancel(); } else { // 已触发命令,重置标记以便下次使用 this.isClickValid = false; } } /// <summary> /// 鼠标离开事件 /// </summary> /// <param name="e"></param> protected override void OnMouseLeave(MouseEventArgs e) { // 鼠标离开按钮,取消延迟任务 this.delayCancellationTokenSource?.Cancel(); } }
使用示例
在XAML中直接引用该自定义按钮,配置延迟时长并绑定命令:
<Window xmlns:local="clr-namespace:YourNamespace"> <local:DelayButton Content="长按1秒触发" DelayInMilliseconds="1000" DelayCommand="{Binding YourCommand}" /> </Window>
内容的提问来源于stack exchange,提问作者ZhuYajun
相关产品推荐
相关产品推荐

