c#如何完全禁用用户按钮

Posted

技术标签:

【中文标题】c#如何完全禁用用户按钮【英文标题】:c# how to completely disable a user button 【发布时间】:2014-06-07 17:57:25 【问题描述】:

我有一个带有一个窗体窗口的 C# 应用程序,上面有一个按钮,我将调用 myButton。我有一个附加的事件,myButton_Click。我想要做的是禁用按钮,并且在 myButton_Click 方法中的操作正在运行时不允许使用按钮的任何用户界面。

目前我从myButton_Click 方法中启动另一个可执行文件,就像我说的那样,我不希望在其他应用程序运行时进行任何用户交互。我遇到的问题是,即使按钮被myButton.Enabled == false; 禁用,如果我在关闭从“myButton_Click”中启动的正在运行的应用程序后多次单击禁用按钮,方法“@ 987654327@' 被召回的次数与我之前单击禁用按钮的次数一样多。

简而言之,我想要一种方法来确保在我禁用的按钮上运行外部应用程序时,不会存储/累积任何操作/按钮点击。

例如

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

谢谢

【问题讨论】:

试试 myButton.Visible = false; 另一种方法可能是检查应用程序是否已经在运行,如果是则忽略按钮点击。 【参考方案1】:

UI 线程被您的外部 EXE 阻塞,它正在排队这些点击事件。正确的解决方案是使用这样的后台工作者:

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();

【讨论】:

【参考方案2】:

我认为使用 async/await 可以提供更简洁的解决方案

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;

【讨论】:

我认为我无法访问 TaskCompletionSource,我使用的是 3.5 网络。 @67vette427 您现在明白为什么需要对问题进行良好的标记visual-studio 不相关,因为即使使用记事本也可以做到到目前为止你做了什么) 什么?了解良好的标记,但记事本与 C# 有关系吗? @67vette427 你甚至可以在不使用 VS 的情况下编写代码。记事本 + csc 就够了。 OK,你可以在记事本里写,然后怎么编译呢?【参考方案3】:

我很惊讶你竟然遇到了这个问题。可能是 Windows 消息没有足够快地禁用按钮。您可以尝试在myButton.Enabled = false; 之后放置DoEvents() 指令

【讨论】:

这也有效。但是从 exeProcess.WaitForExit() 出来后,DoEvents 必须继续。

以上是关于c#如何完全禁用用户按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何完全禁用任何鼠标单击

如何在winform c#中禁用按钮时将焦点设置在按钮上?

禁用 WPF 窗口标题栏中的关闭按钮 (C#)

如何使用javascript禁用后退和前进按钮

C#如何禁用在主线程上运行的按钮?

实现a标签按钮完全禁用