Прочитать на английском

Поделиться через


Практическое руководство. Распознавание одиночных и двойных щелчков

Как правило, одиночное событие щелчок инициирует действие пользовательского интерфейса, а событие двойной щелчок расширяет его. Например, одним щелчком мыши обычно выбирается элемент, а двойным щелчком мыши этот элемент изменяется. Однако события щелчков Windows Forms непросто приспособить к сценарию, в котором щелчок и двойной щелчок выполняют несовместимые действия, поскольку действие, привязанное к событию Click или MouseClick, выполняется перед действием, привязанным к событию DoubleClick или MouseDoubleClick. В этом разделе показаны два способа решения этой проблемы. Одним из решений является обработка события двойного щелчка и откат действий при обработке события щелчка. В редких случаях может потребоваться имитировать поведение при одинарном и двойном щелчке при обработке событий MouseDown и с помощью свойств DoubleClickTime и DoubleClickSize класса SystemInformation. Производится измерение времени между щелчками мышью и, если второе нажатие происходит до того, как DoubleClickTime достигнет значения и кнопка мыши была нажата, когда курсор находился в прямоугольнике, заданном DoubleClickSize, то выполняется действие двойного щелчка; в противном случае выполняется действие щелчка.

Выполнение отката щелчка кнопкой мыши

  • Убедитесь, что элемент управления, с которым вы работаете, имеет стандартное поведение при двойном щелчке мышью. В противном случае задействуйте элемент управления с помощью метода SetStyle. Обработайте событие двойного щелчка и откат к одиночному щелчку кнопкой мыши, а также действие двойного щелчка. В следующем примере кода показано, как создать пользовательскую кнопку с включенным двойным щелчком мыши, а также как откатить к одиночному щелчку в коде обработки событий двойного щелчка.

    C#
    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. Выполните необходимые действия в зависимости от того, имеет ли место щелчок или двойной щелчок кнопкой мыши. В следующем примере кода показано, как это сделать.

    C#
    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);
            }
        }
    }
    

Компиляция кода

Для этих примеров требуются:

  • ссылки на сборки System, System.Drawing и System.Windows.Forms.

См. также