我处理了Image
PreviewMouseLeftButtonDown
事件的ClickCount
控件。
逻辑是在单击时发生更改图像内容,并在双击时激活其他视觉样式。
我知道'use strict';
//app global variable
//this is the controller that handles post requests
//declare services as dependecies $http, $location, custom service apiServiceWeb
app.controller('navigationController', function($scope, $route, $rootScope, $http, $location, $cookies, setCredentials) {
//get what is in the cookie
var cookieValue = setCredentials.getCookie('globals');
if (cookieValue == '[object Object]') {
//redirect to home
$location.path("/");
//remove cookie
//setCredentials.removeCookie('globals');
}
//hide menu in certain paths
if ($location.path() == '/' || $location.path() == 'signup' || cookieValue == '[object Object]') {
//hide menu
$scope.isConnected = true;
} else {
$rootScope.$watch('globals', function() {
//if a currentUser does NOT exist, the hide menu.
console.log('changed');
// console.log($rootScope.globals);
if (cookieValue = null) {
$scope.isConnected = true;
} else {
//show menu, user is logged in
$scope.isConnected = false;
}
});
}
});
属性就像一些答案所说(e.g. this)并成功区分单击/双击,但问题是单击发生总是,其他是双击点击跟随或不跟随下一刻(这是公平的,无论如何)。因此,双击处理两个操作 - 单击,下一次双击。
问题:是否有任何方法可以防止单击之前发生在双击之后,除了以某种计时器魔术处理这种情况?
修改
我找到了一个好的comment的问题,它与Windows资源管理器进行了类比 - 单击所选文件后如何等待,并开始重命名,确保第一次点击后没有其他点击。
延迟将肯定目的存在以解决此问题,但它是否意味着Windows资源管理器使用完全计时器,或者它可能有一些其他选项(某些可以等待的属性或事件)来保持单击万一发生双击?
答案 0 :(得分:7)
最后没有收到与计时器无关的解决方案的建议(我也没有找到任何解决方案),所以这里有一个简单的例子,说明双击时如何防止单击。
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>
代码隐藏:
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");
}
}
}
进行测试时,在窗口区域进行点击,并在visual studio中跟踪写入输出窗口的消息(菜单视图 - &gt;输出)。
另一种方法是使用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");
}
答案 1 :(得分:4)
我猜你需要使用计时器。为了获得对于双击仍然有效的最大时间,您可以使用以下函数(已测试;输出为500毫秒):
[DllImport("user32.dll")]
static extern uint GetDoubleClickTime();
(来源:how to get the double-click-time in WPF)
通常,当您想要绑定到一个WPF控件时有多个值时,可以使用ItemsSource之类的东西,并将其绑定到视图模型中的List。但我想这对图像控制不起作用。因此,您应该使用计时器并使用上述函数的值作为计时器。