Post by "CoreyKou", 2009-02-12, 11:03
-----------------------------------------------------
原文:http://msdn.microsoft.com/zh-cn/library/ms171543(VS.80).aspx
通常,“单击”启动一个用户界面 (UI) 操作,而“双击”扩展该操作。例如,单击通常选择一个项,而双击编辑所选的项。然而,Windows 窗体单击事件并不能轻松适用于下面这种特定方案,即单击和双击执行的操作不兼容的方案,这是因为连接到 Click 或 MouseClick 事件的操作是在连接到 DoubleClick 或 MouseDoubleClick 事件的操作之前执行的。此主题阐释此问题的两种解决办法。一种方法是处理双击事件,然后回滚处理单击事件中执行操作。在极少数情况下,您可能需要通过处理 MouseDown 事件,并通过使用 SystemInformation 类的 DoubleClickTime 和 DoubleClickSize 属性来模拟单击和双击行为。您可以测量两次单击间的时间,如果第二次单击与第一次单击的间隔时间小于 DoubleClickTime 的值,且该单击在 DoubleClickSize 定义的矩形内发生,则执行双击操作;否则,执行单击操作。
回滚单击操作确保您正在处理的控件具有标准的双击行为。如果不具有标准双击行为,请用 SetStyle 方法启用控件。然后处理双击事件,并回滚单击操作及双击操作。下面的代码示例阐释如何创建启用双击行为的自定义按钮,及如何在双击事件处理代码中回滚单击操作。
-
- 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);
- }
- }
- }
复制代码
在 MouseDown 事件中区分单击和双击处理 MouseDown 事件并确定单击位置和两次单击间的时间间隔,方法是使用适当的 SystemInformation 属性和 Timer 组件。根据发生的是单击还是双击,执行适当的操作。下面的代码示例阐释这是如何实现的。
Visual Basic
[url=] 复制代码[/url]
- Imports System
- 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
- 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);
- }
- }
- }
复制代码 |
|