Nasıl yapılır: Tıklamalar ve Çift Tıklamaları Birbirinden Ayırma
Genellikle tek tıklama bir kullanıcı arabirimi (UI) eylemi başlatır ve çift tıklama eylemi genişletir. Örneğin, tek tıklamayla genellikle bir öğe seçilir ve çift tıklama seçili öğeyi düzenler. Ancak, veya olayına bağlı bir eylem veya MouseClick olayına bağlı eylemden önce gerçekleştirildiğinden, Windows Forms tıklama olayları, tıklama ve çift tıklamanın Click uyumsuz eylemler gerçekleştirdiği bir senaryoya DoubleClickMouseDoubleClick kolayca uyum sağlamaz. Bu konu başlığında bu sorunun iki çözümü gösterilmektedir. Bir çözüm, çift tıklama olayını işlemek ve tıklama olayını işlemedeki eylemleri geri almaktır. Nadir durumlarda, olayı işleyerek MouseDown ve sınıfının ve DoubleClickSize özelliklerini kullanarak tıklama ve çift tıklama davranışının benzetimini DoubleClickTimeSystemInformation yapmanız gerekebilir. Tıklamalar arasındaki süreyi ölçersiniz ve değerine DoubleClickTime ulaşılana kadar ikinci bir tıklama gerçekleşirse ve tıklama tarafından DoubleClickSizetanımlanan bir dikdörtgen içindeyse, çift tıklama eylemini gerçekleştirirsiniz; aksi takdirde tıklama eylemini gerçekleştirin.
Tıklama eylemini geri almak için
Üzerinde çalıştığınız denetimin standart çift tıklama davranışına sahip olduğundan emin olun. Aksi takdirde, yöntemiyle SetStyle denetimi etkinleştirin. Çift tıklama olayını işleyin ve tıklama eyleminin yanı sıra çift tıklama eylemini geri alın. Aşağıdaki kod örneğinde, çift tıklama etkin bir özel düğmenin nasıl oluşturulacağı ve çift tıklama olay işleme kodundaki tıklama eyleminin nasıl geri alınacağı gösterilmektedir.
using System; using System.ComponentModel; using System.Drawing; using System.Text; using System.Windows.Forms; namespace MouseRollBackSingleClick { public class Form1 : Form { private DoubleClickButton button1; private FormBorderStyle initialStyle; public Form1() { initialStyle = this.FormBorderStyle; this.ClientSize = new System.Drawing.Size(292, 266); button1 = new DoubleClickButton(); button1.Location = new Point (40,40); button1.Click += new EventHandler(button1_Click); button1.AutoSize = true; this.AllowDrop = true; button1.Text = "Click or Double Click"; button1.DoubleClick += new EventHandler(button1_DoubleClick); this.Controls.Add(button1); } // Handle the double click event. void button1_DoubleClick(object sender, EventArgs e) { // Change the border style back to the initial style. this.FormBorderStyle = initialStyle; MessageBox.Show("Rolled back single click change."); } // Handle the click event. void button1_Click(object sender, EventArgs e) { this.FormBorderStyle = FormBorderStyle.FixedToolWindow; } [STAThread] static void Main() { Application.EnableVisualStyles(); Application.Run(new Form1()); } } public class DoubleClickButton : Button { public DoubleClickButton() : base() { // Set the style so a double click event occurs. SetStyle(ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, true); } } }
Imports System.ComponentModel Imports System.Drawing Imports System.Text Imports System.Windows.Forms Public Class Form1 Inherits Form Private WithEvents button1 As DoubleClickButton Private initialStyle As FormBorderStyle Public Sub New() Me.SuspendLayout() initialStyle = Me.FormBorderStyle Me.ClientSize = New System.Drawing.Size(292, 266) button1 = New DoubleClickButton() button1.Location = New Point(40, 40) button1.AutoSize = True button1.Text = "Click or Double Click" Me.Controls.Add(button1) Me.Name = "Form1" Me.ResumeLayout(False) Me.PerformLayout() End Sub ' Handle the double click event. Private Sub button1_DoubleClick(ByVal sender As Object, ByVal e As EventArgs) _ Handles button1.DoubleClick ' Change the border style back to the initial style. Me.FormBorderStyle = initialStyle MessageBox.Show("Rolled back single click change.") End Sub ' Handle the click event. Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles button1.Click Me.FormBorderStyle = FormBorderStyle.FixedToolWindow End Sub <STAThread()> _ Shared Sub Main() Application.EnableVisualStyles() Application.Run(New Form1()) End Sub End Class Public Class DoubleClickButton Inherits Button Public Sub New() ' Set the style so a double click event occurs. SetStyle(ControlStyles.StandardClick Or ControlStyles.StandardDoubleClick, True) End Sub End Class
MouseDown olayındaki tıklamaları ayırt etmek için
Olayı işleyin MouseDown ve uygun SystemInformation özellikleri ve bir Timer bileşeni kullanarak tıklamalar arasındaki konum ve zaman aralığını belirleyin. Tıklama veya çift tıklamanın gerçekleştirilip gerçekleşmediğine bağlı olarak uygun eylemi gerçekleştirin. Aşağıdaki kod örneğinde bunun nasıl yapılabilmesi gösterilmektedir.
#using <System.Drawing.dll> #using <System.Windows.Forms.dll> #using <System.dll> using namespace System; using namespace System::Drawing; using namespace System::Windows::Forms; namespace SingleVersusDoubleClick { public ref class Form1 : public Form { private: Rectangle hitTestRectangle; private: Rectangle doubleClickRectangle; private: TextBox^ outputBox; private: Timer^ doubleClickTimer; private: ProgressBar^ doubleClickBar; private: Label^ hitTestLabel; private: Label^ timerLabel; private: bool isFirstClick; private: bool isDoubleClick; private: int milliseconds; public: Form1() { hitTestRectangle = Rectangle(); hitTestRectangle.Location = Point(30, 20); hitTestRectangle.Size = System::Drawing::Size(100, 40); doubleClickRectangle = Rectangle(); outputBox = gcnew TextBox(); outputBox->Location = Point(30, 120); outputBox->Size = System::Drawing::Size(200, 100); outputBox->AutoSize = false; outputBox->Multiline = true; doubleClickTimer = gcnew Timer(); doubleClickTimer->Interval = 100; doubleClickTimer->Tick += gcnew EventHandler(this, &Form1::doubleClickTimer_Tick); doubleClickBar = gcnew ProgressBar(); doubleClickBar->Location = Point(30, 85); doubleClickBar->Minimum = 0; doubleClickBar->Maximum = SystemInformation::DoubleClickTime; hitTestLabel = gcnew Label(); hitTestLabel->Location = Point(30, 5); hitTestLabel->Size = System::Drawing::Size(100, 15); hitTestLabel->Text = "Hit test rectangle:"; timerLabel = gcnew Label(); timerLabel->Location = Point(30, 70); timerLabel->Size = System::Drawing::Size(100, 15); timerLabel->Text = "Double click timer:"; isFirstClick = true; this->Paint += gcnew PaintEventHandler(this, &Form1::Form1_Paint); this->MouseDown += gcnew MouseEventHandler(this, &Form1::Form1_MouseDown); this->Controls-> AddRange(gcnew array<Control^> { doubleClickBar, outputBox, hitTestLabel, timerLabel }); } // Detect a valid single click or double click. private: void Form1_MouseDown(Object^ sender, MouseEventArgs^ e) { // Verify that the mouse click is in the main hit // test rectangle. if (!hitTestRectangle.Contains(e->Location)) { return; } // This is the first mouse click. if (isFirstClick) { isFirstClick = false; // Determine the location and size of the double click // rectangle area to draw around the cursor point. doubleClickRectangle = Rectangle( e->X - (SystemInformation::DoubleClickSize.Width / 2), e->Y - (SystemInformation::DoubleClickSize.Height / 2), SystemInformation::DoubleClickSize.Width, SystemInformation::DoubleClickSize.Height); Invalidate(); // Start the double click timer. doubleClickTimer->Start(); } // This is the second mouse click. else { // Verify that the mouse click is within the double click // rectangle and is within the system-defined double // click period. if (doubleClickRectangle.Contains(e->Location) && milliseconds < SystemInformation::DoubleClickTime) { isDoubleClick = true; } } } private: void doubleClickTimer_Tick(Object^ sender, EventArgs^ e) { milliseconds += 100; doubleClickBar->Increment(100); // The timer has reached the double click time limit. if (milliseconds >= SystemInformation::DoubleClickTime) { doubleClickTimer->Stop(); if (isDoubleClick) { outputBox->AppendText("Perform double click action"); outputBox->AppendText(Environment::NewLine); } else { outputBox->AppendText("Perform single click action"); outputBox->AppendText(Environment::NewLine); } // Allow the MouseDown event handler to process clicks again. isFirstClick = true; isDoubleClick = false; milliseconds = 0; doubleClickBar->Value = 0; } } // Paint the hit test and double click rectangles. private: void Form1_Paint(Object^ sender, PaintEventArgs^ e) { // Draw the border of the main hit test rectangle. e->Graphics->DrawRectangle(Pens::Black, hitTestRectangle); // Fill in the double click rectangle. e->Graphics->FillRectangle(Brushes::Blue, doubleClickRectangle); } }; } [STAThread] int main() { Application::EnableVisualStyles(); Application::Run(gcnew SingleVersusDoubleClick::Form1); }
using System; using System.Drawing; using System.Windows.Forms; namespace SingleVersusDoubleClick { class Form1 : Form { private Rectangle hitTestRectangle = new Rectangle(); private Rectangle doubleClickRectangle = new Rectangle(); private TextBox textBox1 = new TextBox(); private Timer doubleClickTimer = new Timer(); private ProgressBar doubleClickBar = new ProgressBar(); private Label label1 = new Label(); private Label label2 = new Label(); private bool isFirstClick = true; private bool isDoubleClick = false; private int milliseconds = 0; [STAThread] public static void Main() { Application.EnableVisualStyles(); Application.Run(new Form1()); } public Form1() { label1.Location = new Point(30, 5); label1.Size = new Size(100, 15); label1.Text = "Hit test rectangle:"; label2.Location = new Point(30, 70); label2.Size = new Size(100, 15); label2.Text = "Double click timer:"; hitTestRectangle.Location = new Point(30, 20); hitTestRectangle.Size = new Size(100, 40); doubleClickTimer.Interval = 100; doubleClickTimer.Tick += new EventHandler(doubleClickTimer_Tick); doubleClickBar.Location = new Point(30, 85); doubleClickBar.Minimum = 0; doubleClickBar.Maximum = SystemInformation.DoubleClickTime; textBox1.Location = new Point(30, 120); textBox1.Size = new Size(200, 100); textBox1.AutoSize = false; textBox1.Multiline = true; this.Paint += new PaintEventHandler(Form1_Paint); this.MouseDown += new MouseEventHandler(Form1_MouseDown); this.Controls.AddRange(new Control[] { doubleClickBar, textBox1, label1, label2 }); } // Detect a valid single click or double click. void Form1_MouseDown(object sender, MouseEventArgs e) { // Verify that the mouse click is in the main hit // test rectangle. if (!hitTestRectangle.Contains(e.Location)) { return; } // This is the first mouse click. if (isFirstClick) { isFirstClick = false; // Determine the location and size of the double click // rectangle area to draw around the cursor point. doubleClickRectangle = new Rectangle( e.X - (SystemInformation.DoubleClickSize.Width / 2), e.Y - (SystemInformation.DoubleClickSize.Height / 2), SystemInformation.DoubleClickSize.Width, SystemInformation.DoubleClickSize.Height); Invalidate(); // Start the double click timer. doubleClickTimer.Start(); } // This is the second mouse click. else { // Verify that the mouse click is within the double click // rectangle and is within the system-defined double // click period. if (doubleClickRectangle.Contains(e.Location) && milliseconds < SystemInformation.DoubleClickTime) { isDoubleClick = true; } } } void doubleClickTimer_Tick(object sender, EventArgs e) { milliseconds += 100; doubleClickBar.Increment(100); // The timer has reached the double click time limit. if (milliseconds >= SystemInformation.DoubleClickTime) { doubleClickTimer.Stop(); if (isDoubleClick) { textBox1.AppendText("Perform double click action"); textBox1.AppendText(Environment.NewLine); } else { textBox1.AppendText("Perform single click action"); textBox1.AppendText(Environment.NewLine); } // Allow the MouseDown event handler to process clicks again. isFirstClick = true; isDoubleClick = false; milliseconds = 0; doubleClickBar.Value = 0; } } // Paint the hit test and double click rectangles. void Form1_Paint(object sender, PaintEventArgs e) { // Draw the border of the main hit test rectangle. e.Graphics.DrawRectangle(Pens.Black, hitTestRectangle); // Fill in the double click rectangle. e.Graphics.FillRectangle(Brushes.Blue, doubleClickRectangle); } } }
Imports System.Drawing Imports System.Windows.Forms Namespace SingleVersusDoubleClick Class Form1 Inherits Form Private hitTestRectangle As New Rectangle() Private doubleClickRectangle As New Rectangle() Private textBox1 As New TextBox() Private WithEvents doubleClickTimer As New Timer() Private doubleClickBar As New ProgressBar() Private label1 As New Label() Private label2 As New Label() Private isFirstClick As Boolean = True Private isDoubleClick As Boolean = False Private milliseconds As Integer = 0 <STAThread()> _ Public Shared Sub Main() Application.EnableVisualStyles() Application.Run(New Form1()) End Sub Public Sub New() label1.Location = New Point(30, 5) label1.Size = New Size(100, 15) label1.Text = "Hit test rectangle:" label2.Location = New Point(30, 70) label2.Size = New Size(100, 15) label2.Text = "Double click timer:" hitTestRectangle.Location = New Point(30, 20) hitTestRectangle.Size = New Size(100, 40) doubleClickTimer.Interval = 100 doubleClickBar.Location = New Point(30, 85) doubleClickBar.Minimum = 0 doubleClickBar.Maximum = SystemInformation.DoubleClickTime textBox1.Location = New Point(30, 120) textBox1.Size = New Size(200, 100) textBox1.AutoSize = False textBox1.Multiline = True Me.Controls.Add(doubleClickBar) Me.Controls.Add(textBox1) Me.Controls.Add(label1) Me.Controls.Add(label2) End Sub ' Detect a valid single click or double click. Sub Form1_MouseDown(ByVal sender As Object, _ ByVal e As MouseEventArgs) Handles Me.MouseDown ' Verify that the mouse click is in the main hit ' test rectangle. If Not hitTestRectangle.Contains(e.Location) Then Return End If ' This is the first mouse click. If isFirstClick = True Then isFirstClick = False ' Determine the location and size of the double click ' rectangle to draw around the cursor point. doubleClickRectangle = New Rectangle( _ e.X - (SystemInformation.DoubleClickSize.Width / 2), _ e.Y - (SystemInformation.DoubleClickSize.Height / 2), _ SystemInformation.DoubleClickSize.Width, _ SystemInformation.DoubleClickSize.Height) Invalidate() ' Start the double click timer. doubleClickTimer.Start() ' This is the second mouse click. Else ' Verify that the mouse click is within the double click ' rectangle and is within the system-defined double ' click period. If doubleClickRectangle.Contains(e.Location) And _ milliseconds < SystemInformation.DoubleClickTime Then isDoubleClick = True End If End If End Sub Sub doubleClickTimer_Tick(ByVal sender As Object, _ ByVal e As EventArgs) Handles doubleClickTimer.Tick milliseconds += 100 doubleClickBar.Increment(100) ' The timer has reached the double click time limit. If milliseconds >= SystemInformation.DoubleClickTime Then doubleClickTimer.Stop() If isDoubleClick Then textBox1.AppendText("Perform double click action") textBox1.AppendText(Environment.NewLine) Else textBox1.AppendText("Perform single click action") textBox1.AppendText(Environment.NewLine) End If ' Allow the MouseDown event handler to process clicks again. isFirstClick = True isDoubleClick = False milliseconds = 0 doubleClickBar.Value = 0 End If End Sub ' Paint the hit test and double click rectangles. Sub Form1_Paint(ByVal sender As Object, _ ByVal e As PaintEventArgs) Handles Me.Paint ' Draw the border of the main hit test rectangle. e.Graphics.DrawRectangle(Pens.Black, hitTestRectangle) ' Fill in the double click rectangle. e.Graphics.FillRectangle(Brushes.Blue, doubleClickRectangle) End Sub End Class End Namespace
Kod Derleniyor
Bu örnekler şunları gerektirir:
- System, System.Drawing ve System.Windows.Forms derlemelerine başvurular.
Ayrıca bkz.
.NET Desktop feedback
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin