找回密码
 立即注册

QQ登录

只需一步,快速开始

Carl

版主

49

主题

213

帖子

962

积分

版主

Rank: 7Rank: 7Rank: 7

积分
962

活字格认证微信认证勋章

QQ
Carl
版主   /  发表于:2009-12-16 10:50  /   查看:7948  /  回复:0
Post by "CoreyKou", 2009-02-12, 11:03
-----------------------------------------------------

原文:http://msdn.microsoft.com/zh-cn/library/ms171543(VS.80).aspx

通常,“单击”启动一个用户界面 (UI) 操作,而“双击”扩展该操作。例如,单击通常选择一个项,而双击编辑所选的项。然而,Windows 窗体单击事件并不能轻松适用于下面这种特定方案,即单击和双击执行的操作不兼容的方案,这是因为连接到 ClickMouseClick 事件的操作是在连接到 DoubleClickMouseDoubleClick 事件的操作之前执行的。此主题阐释此问题的两种解决办法。一种方法是处理双击事件,然后回滚处理单击事件中执行操作。在极少数情况下,您可能需要通过处理 MouseDown 事件,并通过使用 SystemInformation 类的 DoubleClickTimeDoubleClickSize 属性来模拟单击和双击行为。您可以测量两次单击间的时间,如果第二次单击与第一次单击的间隔时间小于 DoubleClickTime 的值,且该单击在 DoubleClickSize 定义的矩形内发生,则执行双击操作;否则,执行单击操作。
回滚单击操作确保您正在处理的控件具有标准的双击行为。如果不具有标准双击行为,请用 SetStyle 方法启用控件。然后处理双击事件,并回滚单击操作及双击操作。下面的代码示例阐释如何创建启用双击行为的自定义按钮,及如何在双击事件处理代码中回滚单击操作。


  1. using System;
  2. using System.ComponentModel;
  3. using System.Drawing;
  4. using System.Text;
  5. using System.Windows.Forms;

  6. namespace MouseRollBackSingleClick
  7. {
  8.     public class Form1 : Form
  9.     {
  10.         private DoubleClickButton button1;
  11.         private FormBorderStyle initialStyle;
  12.       
  13.         public Form1()
  14.         {
  15.             initialStyle = this.FormBorderStyle;
  16.             this.ClientSize = new System.Drawing.Size(292, 266);
  17.             button1 = new DoubleClickButton();
  18.             button1.Location = new Point (40,40);
  19.             button1.Click += new EventHandler(button1_Click);
  20.             button1.AutoSize = true;
  21.             this.AllowDrop = true;
  22.             button1.Text = "Click or Double Click";
  23.             button1.DoubleClick += new EventHandler(button1_DoubleClick);
  24.             this.Controls.Add(button1);
  25.            
  26.         }

  27.         
  28.         // Handle the double click event.
  29.         void button1_DoubleClick(object sender, EventArgs e)
  30.         {
  31.             // Change the border style back to the initial style.
  32.             this.FormBorderStyle = initialStyle;
  33.             MessageBox.Show("Rolled back single click change.");
  34.         }

  35.         // Handle the click event.
  36.         void button1_Click(object sender, EventArgs e)
  37.         {
  38.             this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
  39.         }

  40.         [STAThread]
  41.         static void Main()
  42.         {
  43.             Application.EnableVisualStyles();
  44.             Application.Run(new Form1());
  45.         }

  46.         
  47.     }
  48.     public class DoubleClickButton : Button
  49.     {
  50.         public DoubleClickButton() : base()
  51.         {
  52.             // Set the style so a double click event occurs.
  53.             SetStyle(ControlStyles.StandardClick |
  54.                 ControlStyles.StandardDoubleClick, true);
  55.         }
  56.     }
  57. }
复制代码

在 MouseDown 事件中区分单击和双击处理 MouseDown 事件并确定单击位置和两次单击间的时间间隔,方法是使用适当的 SystemInformation 属性和 Timer 组件。根据发生的是单击还是双击,执行适当的操作。下面的代码示例阐释这是如何实现的。
Visual Basic
[url=] 复制代码[/url]

  1. Imports System
  2. Imports System.Drawing
  3. Imports System.Windows.Forms

  4. Namespace SingleVersusDoubleClick

  5.     Class Form1
  6.         Inherits Form
  7.         Private hitTestRectangle As New Rectangle()
  8.         Private doubleClickRectangle As New Rectangle()
  9.         Private textBox1 As New TextBox()
  10.         Private WithEvents doubleClickTimer As New Timer()
  11.         Private doubleClickBar As New ProgressBar()
  12.         Private label1 As New Label()
  13.         Private label2 As New Label()
  14.         Private isFirstClick As Boolean = True
  15.         Private isDoubleClick As Boolean = False
  16.         Private milliseconds As Integer = 0

  17.         <STAThread()> _
  18.         Public Shared Sub Main()
  19.             Application.EnableVisualStyles()
  20.             Application.Run(New Form1())
  21.         End Sub

  22.         Public Sub New()
  23.             label1.Location = New Point(30, 5)
  24.             label1.Size = New Size(100, 15)
  25.             label1.Text = "Hit test rectangle:"

  26.             label2.Location = New Point(30, 70)
  27.             label2.Size = New Size(100, 15)
  28.             label2.Text = "Double click timer:"

  29.             hitTestRectangle.Location = New Point(30, 20)
  30.             hitTestRectangle.Size = New Size(100, 40)
  31.             doubleClickTimer.Interval = 100

  32.             doubleClickBar.Location = New Point(30, 85)
  33.             doubleClickBar.Minimum = 0
  34.             doubleClickBar.Maximum = SystemInformation.DoubleClickTime

  35.             textBox1.Location = New Point(30, 120)
  36.             textBox1.Size = New Size(200, 100)
  37.             textBox1.AutoSize = False
  38.             textBox1.Multiline = True

  39.             Me.Controls.Add(doubleClickBar)
  40.             Me.Controls.Add(textBox1)
  41.             Me.Controls.Add(label1)
  42.             Me.Controls.Add(label2)
  43.         End Sub

  44.         ' Detect a valid single click or double click.
  45.         Sub Form1_MouseDown(ByVal sender As Object, _
  46.             ByVal e As MouseEventArgs) Handles Me.MouseDown

  47.             ' Verify that the mouse click is in the main hit
  48.             ' test rectangle.
  49.             If Not hitTestRectangle.Contains(e.Location) Then
  50.                 Return
  51.             End If

  52.             ' This is the first mouse click.
  53.             If isFirstClick = True Then
  54.                 isFirstClick = False

  55.                 ' Determine the location and size of the double click
  56.                 ' rectangle to draw around the cursor point.
  57.                 doubleClickRectangle = New Rectangle( _
  58.                     e.X - (SystemInformation.DoubleClickSize.Width / 2), _
  59.                     e.Y - (SystemInformation.DoubleClickSize.Height / 2), _
  60.                     SystemInformation.DoubleClickSize.Width, _
  61.                     SystemInformation.DoubleClickSize.Height)
  62.                 Invalidate()

  63.                 ' Start the double click timer.
  64.                 doubleClickTimer.Start()

  65.             ' This is the second mouse click.
  66.             Else
  67.                 ' Verify that the mouse click is within the double click
  68.                 ' rectangle and is within the system-defined double
  69.                 ' click period.
  70.                 If doubleClickRectangle.Contains(e.Location) And _
  71.                     milliseconds < SystemInformation.DoubleClickTime Then
  72.                     isDoubleClick = True
  73.                 End If
  74.             End If
  75.         End Sub

  76.         Sub doubleClickTimer_Tick(ByVal sender As Object, _
  77.             ByVal e As EventArgs) Handles doubleClickTimer.Tick

  78.             milliseconds += 100
  79.             doubleClickBar.Increment(100)

  80.             ' The timer has reached the double click time limit.
  81.             If milliseconds >= SystemInformation.DoubleClickTime Then
  82.                 doubleClickTimer.Stop()

  83.                 If isDoubleClick Then
  84.                     textBox1.AppendText("Perform double click action")
  85.                     textBox1.AppendText(Environment.NewLine)
  86.                 Else
  87.                     textBox1.AppendText("Perform single click action")
  88.                     textBox1.AppendText(Environment.NewLine)
  89.                 End If

  90.                 ' Allow the MouseDown event handler to process clicks again.
  91.                 isFirstClick = True
  92.                 isDoubleClick = False
  93.                 milliseconds = 0
  94.                 doubleClickBar.Value = 0
  95.             End If
  96.         End Sub

  97.         ' Paint the hit test and double click rectangles.
  98.         Sub Form1_Paint(ByVal sender As Object, _
  99.             ByVal e As PaintEventArgs) Handles Me.Paint

  100.             ' Draw the border of the main hit test rectangle.
  101.             e.Graphics.DrawRectangle(Pens.Black, hitTestRectangle)

  102.             ' Fill in the double click rectangle.
  103.             e.Graphics.FillRectangle(Brushes.Blue, doubleClickRectangle)
  104.         End Sub
  105.     End Class
  106. End Namespace
  107. using System;
  108. using System.Drawing;
  109. using System.Windows.Forms;

  110. namespace SingleVersusDoubleClick
  111. {
  112.     class Form1 : Form
  113.     {
  114.         private Rectangle hitTestRectangle = new Rectangle();
  115.         private Rectangle doubleClickRectangle = new Rectangle();
  116.         private TextBox textBox1 = new TextBox();
  117.         private Timer doubleClickTimer = new Timer();
  118.         private ProgressBar doubleClickBar = new ProgressBar();
  119.         private Label label1 = new Label();
  120.         private Label label2 = new Label();
  121.         private bool isFirstClick = true;
  122.         private bool isDoubleClick = false;
  123.         private int milliseconds = 0;

  124.         [STAThread]
  125.         public static void Main()
  126.         {
  127.             Application.EnableVisualStyles();
  128.             Application.Run(new Form1());
  129.         }

  130.         public Form1()
  131.         {
  132.             label1.Location = new Point(30, 5);
  133.             label1.Size = new Size(100, 15);
  134.             label1.Text = "Hit test rectangle:";

  135.             label2.Location = new Point(30, 70);
  136.             label2.Size = new Size(100, 15);
  137.             label2.Text = "Double click timer:";

  138.             hitTestRectangle.Location = new Point(30, 20);
  139.             hitTestRectangle.Size = new Size(100, 40);

  140.             doubleClickTimer.Interval = 100;
  141.             doubleClickTimer.Tick +=
  142.                 new EventHandler(doubleClickTimer_Tick);

  143.             doubleClickBar.Location = new Point(30, 85);
  144.             doubleClickBar.Minimum = 0;
  145.             doubleClickBar.Maximum = SystemInformation.DoubleClickTime;

  146.             textBox1.Location = new Point(30, 120);
  147.             textBox1.Size = new Size(200, 100);
  148.             textBox1.AutoSize = false;
  149.             textBox1.Multiline = true;

  150.             this.Paint += new PaintEventHandler(Form1_Paint);
  151.             this.MouseDown += new MouseEventHandler(Form1_MouseDown);
  152.             this.Controls.AddRange(new Control[] { doubleClickBar, textBox1,
  153.                 label1, label2 });
  154.         }

  155.         // Detect a valid single click or double click.
  156.         void Form1_MouseDown(object sender, MouseEventArgs e)
  157.         {
  158.             // Verify that the mouse click is in the main hit
  159.             // test rectangle.
  160.             if (!hitTestRectangle.Contains(e.Location))
  161.             {
  162.                 return;
  163.             }

  164.             // This is the first mouse click.
  165.             if (isFirstClick)
  166.             {
  167.                 isFirstClick = false;

  168.                 // Determine the location and size of the double click
  169.                 // rectangle area to draw around the cursor point.
  170.                 doubleClickRectangle = new Rectangle(
  171.                     e.X - (SystemInformation.DoubleClickSize.Width / 2),
  172.                     e.Y - (SystemInformation.DoubleClickSize.Height / 2),
  173.                     SystemInformation.DoubleClickSize.Width,
  174.                     SystemInformation.DoubleClickSize.Height);
  175.                 Invalidate();

  176.                 // Start the double click timer.
  177.                 doubleClickTimer.Start();
  178.             }

  179.             // This is the second mouse click.
  180.             else
  181.             {
  182.                 // Verify that the mouse click is within the double click
  183.                 // rectangle and is within the system-defined double
  184.                 // click period.
  185.                 if (doubleClickRectangle.Contains(e.Location) &amp;&amp;
  186.                     milliseconds < SystemInformation.DoubleClickTime)
  187.                 {
  188.                     isDoubleClick = true;
  189.                 }
  190.             }
  191.         }

  192.         void doubleClickTimer_Tick(object sender, EventArgs e)
  193.         {
  194.             milliseconds += 100;
  195.             doubleClickBar.Increment(100);

  196.             // The timer has reached the double click time limit.
  197.             if (milliseconds >= SystemInformation.DoubleClickTime)
  198.             {
  199.                 doubleClickTimer.Stop();

  200.                 if (isDoubleClick)
  201.                 {
  202.                     textBox1.AppendText("Perform double click action");
  203.                     textBox1.AppendText(Environment.NewLine);
  204.                 }
  205.                 else
  206.                 {
  207.                     textBox1.AppendText("Perform single click action");
  208.                     textBox1.AppendText(Environment.NewLine);
  209.                 }

  210.                 // Allow the MouseDown event handler to process clicks again.
  211.                 isFirstClick = true;
  212.                 isDoubleClick = false;
  213.                 milliseconds = 0;
  214.                 doubleClickBar.Value = 0;
  215.             }
  216.         }

  217.         // Paint the hit test and double click rectangles.
  218.         void Form1_Paint(object sender, PaintEventArgs e)
  219.         {
  220.             // Draw the border of the main hit test rectangle.
  221.             e.Graphics.DrawRectangle(Pens.Black, hitTestRectangle);

  222.             // Fill in the double click rectangle.
  223.             e.Graphics.FillRectangle(Brushes.Blue, doubleClickRectangle);
  224.         }
  225.     }
  226. }
复制代码
愿 Engine 归于沉寂,Timer 停止运动,Message Queue 不再流淌,Data Source 为我掌握

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部