Procedimiento para distinguir entre operaciones de clic y de doble clic (Windows Forms para .NET)
Normalmente, un único clic inicia una acción de la interfaz de usuario y un doble clic extiende la acción. Por ejemplo, un clic normalmente selecciona un elemento y un doble clic edita el elemento seleccionado. Sin embargo, los eventos de clic de Windows Forms no se adaptan fácilmente un escenario en el que un clic y un doble clic realizan acciones incompatibles, ya que una acción asociada al evento Click o MouseClick se realiza antes de la acción asociada al evento DoubleClick o MouseDoubleClick. Este tema se muestran dos soluciones a este problema.
Una solución es controlar el evento de doble clic y revertir las acciones en el control del evento de clic. En raras ocasiones, puede que necesite simular el comportamiento de clic y doble clic controlando el evento MouseDown y usando las propiedades DoubleClickTime y DoubleClickSize de la clase SystemInformation. Mida el tiempo entre los clics y si se produce un segundo clic antes de alcanzar el valor de DoubleClickTime y el clic en está dentro de un rectángulo definido por DoubleClickSize, realice la acción de doble clic; de lo contrario, realice la acción de clic.
Para revertir una acción de clic
Asegúrese de que el control con el que trabaja tiene un comportamiento de doble clic estándar. Si no es así, habilite el control con el método SetStyle. Controle el evento de doble clic y revierta la acción de clic, así como la acción de doble clic. En el ejemplo de código siguiente se muestra cómo crear un botón personalizado con el doble clic habilitado, y cómo revertir la acción de clic en el código de control de eventos de doble clic.
En este ejemplo de código se usa un nuevo control de botón que habilita los doble clic:
public partial class DoubleClickButton : Button
{
public DoubleClickButton()
{
// Set the style so a double click event occurs.
SetStyle(ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, true);
}
}
Public Class DoubleClickButton : Inherits Button
Public Sub New()
SetStyle(ControlStyles.StandardClick Or ControlStyles.StandardDoubleClick, True)
End Sub
End Class
En el código siguiente se muestra cómo un formulario cambia el estilo de borde en función de un clic o doble clic en el nuevo control de botón:
public partial class Form1 : Form
{
private FormBorderStyle _initialStyle;
private bool _isDoubleClicking;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
_initialStyle = this.FormBorderStyle;
var button1 = new DoubleClickButton();
button1.Location = new Point(50, 50);
button1.Size = new Size(200, 23);
button1.Text = "Click or Double Click";
button1.Click += Button1_Click;
button1.DoubleClick += Button1_DoubleClick;
Controls.Add(button1);
}
private void Button1_DoubleClick(object sender, EventArgs e)
{
// This flag prevents the click handler logic from running
// A double click raises the click event twice.
_isDoubleClicking = true;
FormBorderStyle = _initialStyle;
}
private void Button1_Click(object sender, EventArgs e)
{
if (_isDoubleClicking)
_isDoubleClicking = false;
else
FormBorderStyle = FormBorderStyle.FixedToolWindow;
}
}
Partial Public Class Form1
Private _initialStyle As FormBorderStyle
Private _isDoubleClicking As Boolean
Public Sub New()
InitializeComponent()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim button1 As New DoubleClickButton
_initialStyle = FormBorderStyle
button1.Location = New Point(50, 50)
button1.Size = New Size(200, 23)
button1.Text = "Click or Double Click"
AddHandler button1.Click, AddressOf Button1_Click
AddHandler button1.DoubleClick, AddressOf Button1_DoubleClick
Controls.Add(button1)
End Sub
Private Sub Button1_DoubleClick(sender As Object, e As EventArgs)
' This flag prevents the click handler logic from running
' A double click raises the click event twice.
_isDoubleClicking = True
FormBorderStyle = _initialStyle
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs)
If _isDoubleClicking Then
_isDoubleClicking = False
Else
FormBorderStyle = FormBorderStyle.FixedToolWindow
End If
End Sub
End Class
Para distinguir entre los clics
Controle el evento MouseDown y determine la ubicación y el intervalo de tiempo entre los clics mediante la propiedad SystemInformation y un componente Timer. Realice las acciones apropiadas en función de si tiene lugar un clic o un doble clic. En el ejemplo de código siguiente se muestra cómo hacer esto.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace project
{
public partial class Form2 : Form
{
private DateTime _lastClick;
private bool _inDoubleClick;
private Rectangle _doubleClickArea;
private TimeSpan _doubleClickMaxTime;
private Action _doubleClickAction;
private Action _singleClickAction;
private Timer _clickTimer;
public Form2()
{
InitializeComponent();
_doubleClickMaxTime = TimeSpan.FromMilliseconds(SystemInformation.DoubleClickTime);
_clickTimer = new Timer();
_clickTimer.Interval = SystemInformation.DoubleClickTime;
_clickTimer.Tick += ClickTimer_Tick;
_singleClickAction = () => MessageBox.Show("Single clicked");
_doubleClickAction = () => MessageBox.Show("Double clicked");
}
private void Form2_MouseDown(object sender, MouseEventArgs e)
{
if (_inDoubleClick)
{
_inDoubleClick = false;
TimeSpan length = DateTime.Now - _lastClick;
// If double click is valid, respond
if (_doubleClickArea.Contains(e.Location) && length < _doubleClickMaxTime)
{
_clickTimer.Stop();
_doubleClickAction();
}
return;
}
// Double click was invalid, restart
_clickTimer.Stop();
_clickTimer.Start();
_lastClick = DateTime.Now;
_inDoubleClick = true;
_doubleClickArea = new Rectangle(e.Location - (SystemInformation.DoubleClickSize / 2),
SystemInformation.DoubleClickSize);
}
private void ClickTimer_Tick(object sender, EventArgs e)
{
// Clear double click watcher and timer
_inDoubleClick = false;
_clickTimer.Stop();
_singleClickAction();
}
}
}
Imports System.Drawing
Imports System.Windows.Forms
Public Class Form2
Private _lastClick As Date
Private _inDoubleClick As Boolean
Private _doubleClickArea As Rectangle
Private _doubleClickMaxTime As TimeSpan
Private _singleClickAction As Action
Private _doubleClickAction As Action
Private WithEvents _clickTimer As Timer
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
_doubleClickMaxTime = TimeSpan.FromMilliseconds(SystemInformation.DoubleClickTime)
_clickTimer = New Timer()
_clickTimer.Interval = SystemInformation.DoubleClickTime
_singleClickAction = Sub()
MessageBox.Show("Single click")
End Sub
_doubleClickAction = Sub()
MessageBox.Show("Double click")
End Sub
End Sub
Private Sub Form2_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown
If _inDoubleClick Then
_inDoubleClick = False
Dim length As TimeSpan = Date.Now - _lastClick
' If double click is valid, respond
If _doubleClickArea.Contains(e.Location) And length < _doubleClickMaxTime Then
_clickTimer.Stop()
Call _doubleClickAction()
End If
Return
End If
' Double click was invalid, restart
_clickTimer.Stop()
_clickTimer.Start()
_lastClick = Date.Now
_inDoubleClick = True
_doubleClickArea = New Rectangle(e.Location - (SystemInformation.DoubleClickSize / 2),
SystemInformation.DoubleClickSize)
End Sub
Private Sub SingleClickTimer_Tick(sender As Object, e As EventArgs) Handles _clickTimer.Tick
' Clear double click watcher and timer
_inDoubleClick = False
_clickTimer.Stop()
Call _singleClickAction()
End Sub
End Class
Vea también
- Información general sobre el uso del mouse (Windows Forms para .NET)
- Uso de eventos del mouse (Windows Forms para .NET)
- Administración de punteros del mouse (Windows Forms para .NET)
- Procedimiento para simular eventos del mouse (Windows Forms para .NET)
- Control.Click
- Control.MouseDown
- Control.SetStyle
.NET Desktop feedback