简体   繁体   中英

c# how to completely disable a user button

I have a C# application with a form window that has a button on it, I'll call myButton . I have an event attached to it, myButton_Click . What I want to do is disable the button and not allow any user interface with the button while the actions within the myButton_Click method are running.

Currently I launch another executable from within the myButton_Click method and like I said I do NOT want any user interaction while the other application is running. The problem I am running into is that even though the button is disabled, by myButton.Enabled == false; , if I click multiple times on the disabled button once I close the running application that was launched from within ' myButton_Click ', the method ' myButton_Click ' gets recalled as many times as I clicked on the disabled button previously.

In short I would like a way to make sure that no actions/button clicks are stored/accumulated while the outside application is running on the button that I disabled.

Eg

private void myButton_Click(object sender, EventArgs e)
{
       myButton.Enabled = false;
       ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.CreateNoWindow = false;
            startInfo.UseShellExecute = false;
            startInfo.FileName = "someapplication.EXE";

            try
            {
                using (Process exeProcess = Process.Start(startInfo))
                {
                    exeProcess.WaitForExit();
                }
            }
            catch{// Log error.   
            }

        myButton.Enabled = true;// turn the button back on
}

Thanks

The UI thread is being blocked by your external EXE and it's queuing up those click events. The proper solution is to use a background worker like this:

private void button1_Click(object sender, EventArgs e)
{
    button1.Enabled = false;

    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += (doWorkSender, doWorkArgs) =>
    {
        // You will want to call your external app here...
        Thread.Sleep(5000);
    };
    worker.RunWorkerCompleted += (completedSender, completedArgs) =>
    {
        button1.Enabled = true;
    };
    worker.RunWorkerAsync();
}

I think using async/await can give a cleaner solution

async private void button1_Click(object sender, EventArgs e)
{
    button1.Enabled = false;
    await RunProcessAsync("notepad.exe");
    button1.Enabled = true;
}


public Task RunProcessAsync(string processName)
{
    TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();

    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.CreateNoWindow = false;
    startInfo.UseShellExecute = false;
    startInfo.FileName = processName;
    var proc = Process.Start(startInfo);
    proc.EnableRaisingEvents = true;
    proc.Exited += (s,e) => tcs.TrySetResult(null);

    return tcs.Task;
}

I'm surprised that you're even getting that problem. It could possibly be that the windows message is not disabling the button quick enough. You could try putting a DoEvents() instruction after myButton.Enabled = false;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM