Sam*_*Sam 5 c# wpf click double-click
我Image控制了PreviewMouseLeftButtonDown事件处理.逻辑是在单击发生时更改图像内容,并在双击时激活其他视觉样式.
我知道ClickCount属性就像一些答案所说的那样(例如这个)并且成功地区分单击/双击,但问题是单击总是发生,其中双击跟随或不跟随下一刻(这是公平的,无论如何).因此,双击处理两个操作 - 单击,下一次双击.
问题:有没有防止单一的点击方法之前是双击后存在的权利,比其他处理这种情况有某种神奇的计时器?
编辑:
我发现了一个好的评论问题,这与Windows资源管理器进行了类比 - 单击所选文件后如何等待,并开始重命名,确保第一次点击后没有其他点击.
延迟肯定会存在以解决这个问题的目的,但它是否意味着Windows资源管理器使用完全计时器,或者它可能有一些其他选项(某些属性或事件可以等待)以保持单击以防双击发生?
最后没有收到与定时器无关的解决方案的建议(我也没有发现任何一个),所以这里是一个简单的例子,当双击发生时如何防止单击.
XAML:
<Window x:Class="StackOverflow.DoubleClickExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="100" Width="150"
MouseDown="RootElement_OnMouseDown">
</Window>
Run Code Online (Sandbox Code Playgroud)
代码隐藏:
namespace StackOverflow.DoubleClickExample
{
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
public partial class MainWindow : Window
{
[DllImport("user32.dll")]
public static extern uint GetDoubleClickTime();
public MainWindow()
{
this.InitializeComponent();
}
private Guid lastGuid = Guid.Empty;
private void RootElement_OnMouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 1)
{
// Create new unique id and save it into field.
var guid = Guid.NewGuid();
this.lastGuid = guid;
// Run task asynchronously for ensuring that there is no another click
// happened in time interval when double-click can occure.
Task.Run(async () =>
{
// Wait system double-click time interval.
await Task.Delay((int)GetDoubleClickTime());
// If no double-click occured in awaited time interval, then
// last saved id (saved when first click occured) will be unchanged.
if (guid == this.lastGuid)
{
// Here is any logic for single-click handling.
Trace.WriteLine("Single-click occured");
}
});
return;
}
// Can be here only when e.ClickCount > 1, so must change last saved unique id.
// After that, asynchronously running task (for single-click) will detect
// that id was changed and so will NOT run single-click logic.
this.lastGuid = Guid.NewGuid();
// Here is any logic for double-click handling.
Trace.WriteLine("Double-click occured");
}
}
}
Run Code Online (Sandbox Code Playgroud)
要进行测试,请在窗口区域中单击并跟踪在visual studio中写入输出窗口的消息(菜单视图 - >输出).
另一种方法是在双击时使用CancellationTokenSource并触发其Cancel方法.只需替换lastGuid字段和RootElement_OnMouseDown方法:
private CancellationTokenSource cancellationTokenSource;
private void RootElement_OnMouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 1)
{
try
{
this.cancellationTokenSource = new CancellationTokenSource();
var token = this.cancellationTokenSource.Token;
// Run task asynchronously for ensuring that there is no another click
// happened in time interval when double-click can occure.
Task.Run(async () =>
{
// Wait system double-click time interval.
await Task.Delay((int)GetDoubleClickTime(), token);
// Here is any logic for single-click handling.
Trace.WriteLine("Single-click occured");
}, token);
}
catch (OperationCanceledException)
{
// This exception always occure when task is cancelled.
// It happening by design, just ignore it.
}
return;
}
// Cancel single-click task.
if (this.cancellationTokenSource != null)
{
this.cancellationTokenSource.Cancel();
}
// Here is any logic for double-click handling.
Trace.WriteLine("Double-click occured");
}
Run Code Online (Sandbox Code Playgroud)