C# Enable/disable 进程退出事件触发时的用户表单不起作用

C# Enable/disable user form when process exited event fires not working

我有这个代码:

private void btnAddDataToCSV_Click(object sender, EventArgs e)
{
    var myProcess = new Process();
    this.Enabled = false;
    myProcess.EnableRaisingEvents = true;
    myProcess.Exited += new EventHandler(Excel_Exit);
    myProcess.StartInfo.FileName = "D:\MyCsvFile.csv";
    myProcess.Start();     
}

public void Excel_Exit(object sender, System.EventArgs e)
{
    MessageBox.Show("Success!!");
    this.Enabled = true;
}

该代码可以使我的 C# 用户表单上的所有按钮变灰并在 Excel 中打开 csv 文件。当我关闭 Excel 时,退出事件会触发并显示一条消息“成功!!”但它不会在关闭后重新启用按钮 Excel。

我遇到错误

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll

this.Enabled = true; 行。

正如您从我下面的评论中看到的那样。我现在意识到我什至不知道如何禁用一个按钮。

private void btnAddDataToCSV_Click(object sender, EventArgs e)
{
    var myProcess = new Process();
    button1.Enabled = false;
    myProcess.EnableRaisingEvents = true;
    myProcess.Exited += new EventHandler(Excel_Exit);
    myProcess.StartInfo.FileName = "D:\MyCsvFile.csv";
    myProcess.Start();     
}

public void Excel_Exit(object sender, System.EventArgs e)
{
    button1.Enabled = true;
}

事件正在触发,因为下面的代码有效...(显示成功!!)

private void btnAddDataToCSV_Click(object sender, EventArgs e)
{
    var myProcess = new Process();
    myProcess.EnableRaisingEvents = true;
    myProcess.Exited += new EventHandler(Excel_Exit);
    myProcess.StartInfo.FileName = "D:\MyCsvFile.csv";
    myProcess.Start();     
}

public void Excel_Exit(object sender, System.EventArgs e)
{
    MessageBox.Show("Success!!");
}

如有任何帮助,我们将不胜感激。

this.Enabled = false;替换为AddtoCsv.Enabled = false;

private void btnAddDataToCSV_Click(object sender, EventArgs e)
            {
                var myProcess = new Process();
                AddtoCsv.Enabled = false;
                myProcess.EnableRaisingEvents = true;
                myProcess.Exited += new EventHandler(Excel_Exit);
                myProcess.StartInfo.FileName = "E:\MyCsvFile.csv";
                myProcess.Start();
            }

只需在 Excel_Exit 方法中调用 SetButtonState 方法,不要忘记声明委托。

        public void Excel_Exit(object sender, System.EventArgs e)
        {
            
            // Set Button Enable State True
            SetButtonState();

        }

        private delegate void SafeCallDelegate();
        private void SetButtonState()
        {           

            // check if current thread is same which have created this control
            if (AddtoCsv.InvokeRequired)
            {
                SafeCallDelegate d = new SafeCallDelegate(SetButtonState);                
                AddtoCsv.Invoke(d);                
            }
            else
            {
                AddtoCsv.Enabled = true;
            }
        }

好的...我无法禁用整个表单。但是基于我发现的其他东西,我创建了一个“面板”并将所有按钮放在面板内并且能够启用整个面板。

所以下面的解决方案有效。特别感谢 Paramjot Singh,他发布了另一个适用于单个按钮的解决方案,我不知道如果没有他的帮助我是否能解决这个问题!!

private void btnAddDataToCSV_Click(object sender, EventArgs e)
{
    var myProcess = new Process();
    panel1.Enabled = false;
    myProcess.EnableRaisingEvents = true;
    myProcess.Exited += new EventHandler(Excel_Exit);
    myProcess.StartInfo.FileName = "E:\MyCsvFile.csv";
    myProcess.Start();
}

public void Excel_Exit(object sender, System.EventArgs e)
{
        
    // Set Button Enable State True
    SetButtonState();

}

private delegate void SafeCallDelegate();
private void SetButtonState()
{           

    // check if current thread is same which have created this control
    if (panel1.InvokeRequired)
    {
        SafeCallDelegate d = new SafeCallDelegate(SetButtonState);                
        panel1.Invoke(d);                
    }
    else
    {
        panel1.Enabled = true;
    }
}

我在表单中添加了 2 个控件,并在打开 excel 文件时将其设置为禁用。

private void btnAddDataToCSV_Click(object sender, EventArgs e)
        {
            var myProcess = new Process();
            AddtoCsv.Enabled = false;
            textBox1.Enabled = false;
            checkBox1.Enabled = false;
            myProcess.EnableRaisingEvents = true;
            myProcess.Exited += new EventHandler(Excel_Exit);
            myProcess.StartInfo.FileName = "E:\MyCsvFile.csv";
            myProcess.Start();
        }

之后,获取我们表单中的所有控件并将其传递给 SetButtonState 方法。

    public void Excel_Exit(object sender, System.EventArgs e)
    {

        // Set Button Enable State True
        var controls = this.Controls.Cast<Control>();

        foreach (Control ctrl in controls)
        {
            SetButtonState(ctrl);
        }
        
        
    }

SetButtonState 将调用调用传递的控件的方法,然后我们就可以对控件进行更改。

    private delegate void SafeCallDelegate(Control control);
    private void SetButtonState(Control control)
    {           

        // check if current thread is same which have created this control
        if (control.InvokeRequired)
        {
            SafeCallDelegate d = new SafeCallDelegate(SetButtonState);
            control.Invoke(d, control);                
        }
        else
        {
            control.Enabled = true;                                       
            
        }
    }