Jak rozróżniać kliknięcia i dwukrotne kliknięcia (Windows Forms .NET)
Zazwyczaj pojedyncze kliknięcie inicjuje akcję interfejsu użytkownika i dwukrotne kliknięcie rozszerza akcję. Na przykład jedno kliknięcie zwykle wybiera element, a dwukrotne kliknięcie edytuje wybrany element. Jednak zdarzenia kliknięcia formularzy systemu Windows nie są łatwe w scenariuszu, w którym kliknięcie i dwukrotne kliknięcie wykonują niezgodne akcje, ponieważ akcja powiązana ze Click zdarzeniem lub jest wykonywana przed akcją powiązaną z DoubleClick zdarzeniem lub MouseDoubleClick MouseClick. W tym temacie przedstawiono dwa rozwiązania tego problemu.
Jednym z rozwiązań jest obsługa zdarzenia dwukrotnego kliknięcia i wycofywanie akcji w obsłudze zdarzenia kliknięcia. W rzadkich sytuacjach może być konieczne symulowanie zachowania kliknięcia i dwukrotnego kliknięcia przez obsługę MouseDown zdarzenia i przy użyciu DoubleClickTime właściwości SystemInformation i DoubleClickSize klasy . Mierzysz czas między kliknięciami, a jeśli nastąpi drugie kliknięcie przed osiągnięciem wartości DoubleClickTime , a kliknięcie znajduje się w prostokątze zdefiniowanym przez DoubleClickSizeelement , wykonaj akcję dwukrotnego kliknięcia; w przeciwnym razie wykonaj akcję kliknięcia.
Aby wycofać akcję kliknięcia
Upewnij się, że kontrolka, z którą pracujesz, ma standardowe zachowanie dwukrotnego kliknięcia. Jeśli nie, włącz kontrolkę za pomocą SetStyle metody . Obsłuż zdarzenie dwukrotnego kliknięcia i wycofaj akcję kliknięcia, a także akcję dwukrotnego kliknięcia. W poniższym przykładzie kodu pokazano, jak utworzyć przycisk niestandardowy z włączonym dwukrotnym kliknięciem, a także jak wycofać akcję kliknięcia w kodzie obsługi zdarzeń dwukrotnego kliknięcia.
W tym przykładzie kodu jest używana nowa kontrolka przycisku, która umożliwia dwukrotne kliknięcie:
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
Poniższy kod pokazuje, jak formularz zmienia styl obramowania na podstawie kliknięcia lub dwukrotnego kliknięcia nowej kontrolki przycisku:
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
Aby odróżnić kliknięcia
MouseDown Obsłuż zdarzenie i określ przedział czasu między kliknięciami przy użyciu SystemInformation właściwości i Timer składnika. Wykonaj odpowiednią akcję w zależności od tego, czy odbywa się kliknięcie, czy dwukrotne kliknięcie. Poniższy przykład kodu pokazuje, jak można to zrobić.
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
Zobacz też
.NET Desktop feedback