Windows标准按钮单击事件问题 [英] Windows Standard Button Click Event Issue

查看:55
本文介绍了Windows标准按钮单击事件问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

20多年来(回到VB6和C#.Net早期版本),我使用了button.enabled = false方法,在完成流程时使按钮控件无法使用。  然后我在流程完成后重新启用该按钮。  这可以防止用户多次单击按钮并多次运行一个按钮,这可能对应用程序有害。  网上有几十个代码示例,向您展示如何使用.Enabled = False或使用Button.Click - = Button_Click解除事件处理程序
来解决这个问题。



我已经在VS2015上使用WinForms启动了一个新的应用程序& Windows 10和我现在正在遇到一个我以前从未遇到过的新问题。即使按钮被禁用(按钮显示为灰色),如果我再次单击该按钮,它似乎会按下按钮单击排队
,一旦过程完成并重新启用该按钮,它将立即激活。  如果我使用Enabled方法或事件unwire方法,则会发生这种情况。  
$


$
以下是行为:点击按钮。  按钮有5秒的睡眠时间。  大约2秒后立即再次单击禁用的按钮。  当5秒钟结束时,该按钮将立即处理第二次点击。  我附上了
a代码示例和四个不同的按钮来演示这一点。

For over 20 years (going back to VB6 and C#.Net early days), I have used the button.enabled = false method to make a button control unusable while a process is being completed.  I then re-enable the button after the process completes.  This prevents a user from clicking a button too many times and running a process more than once, which could be harmful to the application.  There are dozens of code examples available on the net that show you how to do this with either the .Enabled = False OR unwiring the event handler with Button.Click -= Button_Click.

I have started a new app using WinForms on VS2015 & Windows 10 and I am now running into what appears to be a new problem that I never had before. Even though the button is disabled (button is grayed), if I click on the button again, it seems to be queuing the button click and it will fire as soon as the process completes and the button is re-enabled.  This happens if I use either the Enabled method or the event unwire method.  


Here's the behavior:  Click the button.  The button has a 5 second sleep.  Immediately click the disabled button again after about 2 seconds.  When the 5 seconds is up, the button will immediately process the 2nd click.  I have attached a code example with four different buttons to demonstrate this.

Form1.cs:               

using System;
using System.Windows.Forms;

namespace WindowsButtonClickIssue
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // Fields
        public int iResult = 0;

        /// <summary>
        /// This click event tests using a Standard Windows Button control
        /// with the Enabled property to see if a 2nd click is prevented
        /// before the 5 second processing time is up.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void windowsButtonTestEnable_Click(object sender, EventArgs e)
        {
            if (!(sender as Control).Enabled)
                return;

            //First, disable the button, so user can't click again while processing.
            windowsButtonTestEnable.Enabled = false;            

            try
            {
                DoSomething();

                //Show the incremented number in the label control.
                lblResults.Text = iResult.ToString();
            }
            catch
            { throw; }
            finally
            {
                //Now reenable the button.
                windowsButtonTestEnable.Enabled = true;
            }
        }

        /// <summary>
        /// This click event tests using a Standard Windows Button control
        /// by unwiring the event handler to see if a 2nd click is prevented
        /// before the 5 second processing time is up.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void windowsButtonTestEvent_Click(object sender, EventArgs e)
        {
            //First, unwire the button click event handler, so user can't click again while processing.            
            windowsButtonTestEvent.Click -= windowsButtonTestEvent_Click;

            try
            {
                DoSomething();

                //Show the incremented number in the label control.
                lblResults.Text = iResult.ToString();
            }
            catch
            { throw; }
            finally
            {
                //Now rewire the button click event handler
                windowsButtonTestEvent.Click += windowsButtonTestEvent_Click;
            }
        }

        /// <summary>
        /// This simulates a process that takes 5 seconds to run.  
        /// However, not sure if Sleep is best way to simulate this.
        /// </summary>
        private void DoSomething()
        {
            System.Threading.Thread.Sleep(5000);
            iResult += 10;
        }

        private void btnClearResults_Click(object sender, EventArgs e)
        {
            iResult = 0;
            lblResults.Text = iResult.ToString();
        }
    }
}

Form1.Designer.cs:

Form1.Designer.cs:

namespace WindowsButtonClickIssue
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.windowsButtonTestEvent = new System.Windows.Forms.Button();
            this.windowsButtonTestEnable = new System.Windows.Forms.Button();
            this.lblResults = new System.Windows.Forms.Label();
            this.btnClearResults = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // windowsButtonTestEvent
            // 
            this.windowsButtonTestEvent.Location = new System.Drawing.Point(106, 91);
            this.windowsButtonTestEvent.Name = "windowsButtonTestEvent";
            this.windowsButtonTestEvent.Size = new System.Drawing.Size(239, 41);
            this.windowsButtonTestEvent.TabIndex = 6;
            this.windowsButtonTestEvent.Text = "Windows Std Button Text Clicks w Event Unwire";
            this.windowsButtonTestEvent.UseVisualStyleBackColor = true;
            this.windowsButtonTestEvent.Click += new System.EventHandler(this.windowsButtonTestEvent_Click);
            // 
            // windowsButtonTestEnable
            // 
            this.windowsButtonTestEnable.Location = new System.Drawing.Point(106, 24);
            this.windowsButtonTestEnable.Name = "windowsButtonTestEnable";
            this.windowsButtonTestEnable.Size = new System.Drawing.Size(239, 41);
            this.windowsButtonTestEnable.TabIndex = 5;
            this.windowsButtonTestEnable.Text = "Windows Std Button Test Clicks w Enable";
            this.windowsButtonTestEnable.UseVisualStyleBackColor = true;
            this.windowsButtonTestEnable.Click += new System.EventHandler(this.windowsButtonTestEnable_Click);
            // 
            // lblResults
            // 
            this.lblResults.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lblResults.Location = new System.Drawing.Point(157, 185);
            this.lblResults.Name = "lblResults";
            this.lblResults.Size = new System.Drawing.Size(157, 42);
            this.lblResults.TabIndex = 7;
            this.lblResults.Text = "Results";
            this.lblResults.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // btnClearResults
            // 
            this.btnClearResults.Location = new System.Drawing.Point(161, 230);
            this.btnClearResults.Name = "btnClearResults";
            this.btnClearResults.Size = new System.Drawing.Size(153, 46);
            this.btnClearResults.TabIndex = 8;
            this.btnClearResults.Text = "Clear Results";
            this.btnClearResults.UseVisualStyleBackColor = true;
            this.btnClearResults.Click += new System.EventHandler(this.btnClearResults_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(470, 383);
            this.Controls.Add(this.btnClearResults);
            this.Controls.Add(this.lblResults);
            this.Controls.Add(this.windowsButtonTestEvent);
            this.Controls.Add(this.windowsButtonTestEnable);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Button windowsButtonTestEvent;
        private System.Windows.Forms.Button windowsButtonTestEnable;
        private System.Windows.Forms.Label lblResults;
        private System.Windows.Forms.Button btnClearResults;
    }
}




推荐答案

您的简单解决方案是在流程开始为true时设置一个开关,并在流程完成时将其设置为false。如果switch为true,则退出并不执行该过程。
Your simple solution is to set a switch when the process starts to true and set it to false when process completes. If switch is true, then exit out and not do the process.


这篇关于Windows标准按钮单击事件问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆