当进程退出事件触发不起作用时,C#启用/禁用用户表单

问题描述

我有代码

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之后,它不会重新启用按钮。

我遇到了错误

System.Windows.Forms.dll中发生了类型为'system.invalidOperationException'的未处理异常

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

只需在SetButtonState方法内调用Excel_Exit方法,别忘了声明委托。

        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;
            }
        }
,

我在表单中添加了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将调用传递的控件的invoke方法,然后我们就可以对控件进行更改。

    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;                                       
            
        }
    }
,

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

因此以下解决方案有效。特别感谢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;
    }
}