繁体   English   中英

从Cplex回调函数C#访问表单上的状态栏

[英]Access statusbar on form from cplex callback function c#

我正在使用将Cplex DLL用于优化操作的C#.Net应用程序,在该操作期间,我想将状态进度写入启动该操作的状态栏。

这是特定表格的总体布局;

namespace ActResMain
{
    public class FormOptimize : System.Windows.Forms.Form
    {
        private callCplex()
        {
            //...
            cplex.Use(new Cplex_ContinuousCallback());
            cplex.Solve()
        }
        public void Update_OptimizeStatusbarPanel(String strText)
        {
                statusBarPanel_1.Text = strText;
                statusBar1.Refresh();
        }
        internal class Cplex_ContinuousCallback : Cplex.ContinuousCallback
        {
            FormOptimize formOpt = new FormOptimize();
            public override void Main()
            {
                //From here I want to edit the statusbar at FormOptimize. I can write progress to console without any problems, but cannot reach function "Update_OptimizeStatusbarPanel".
                //If I include "FormOptimize formOpt = new FormOptimize" here, i get Visual studio exception on illegal window reference.
            }
        }

    }
}

我也尝试过像这样调用Update_OptimizeStatusbarPanel函数:

internal class Cplex_ContinuousCallback : Cplex.ContinuousCallback
            {
                FormOptimize formOpt = new FormOptimize();
                public override void Main()
                {
                    FormCollection fc = Application.OpenForms;
                    var mpc = fc[1];
                    Type type = mpc.GetType(); 
                    MethodInfo dynMethod = type.GetMethod("Update_OptimizeStatusbarPanel");
                    dynMethod.Invoke(mpc, new object[] { String.Format("Running Optimization: {0} iterations ", Niterations)});
                }
            }

但是随后我从Visual Studio中得到一个例外,指出一个线程创建的对象无法从另一个线程修改。

也许这是我很想念的愚蠢之举,但是对我们的帮助非常有用

编辑:我根据Mohammad Dehghans的建议编辑了代码,

public class FormOptimize : System.Windows.Forms.Form
{
    private callCplex()
    {
        cplex.Use(new Cplex_ContinuousCallback(this));
        cplex.Solve()
    }

    internal class Cplex_ContinuousCallback : Cplex.ContinuousCallback
    {
        FormOptimize _formOptimize;
        public Cplex_ContinuousCallback(FormOptimize formOptimize)
        {
            this._formOptimize = formOptimize;
        }

        public override void Main()
        {
            if (Niterations % 10 == 0)
            {
                _formOptimize.Update_OptimizeStatusbarPanel(0, String.Format("Running Optimization: {0} iterations ", Niterations), 0);
            }
        }
    }

    public void Update_OptimizeStatusbarPanel(short panelIndex, String strText, short severity)
    {
        if (statusBar1.InvokeRequired)
            statusBar1.Invoke(new Action<short, string, short>(Update_OptimizeStatusbarPanel), panelIndex, strText, severity);
        else
        {
            if (panelIndex == 0)
            {
                //...
                statusBarPanel_0.Text = strText;
            }
            else if (panelIndex == 1)
            {
                //...
                statusBarPanel_1.Text = strText;

            }
            statusBar1.Refresh();
        }
    }
}

但是这样做显然会破坏某些东西,因为第一次调用statusBar1.Invoke()之后,应用程序才停止。 如果我暂停调试器,它会说cplex.Solve()正在执行,但是什么也没有发生。

首先,您需要将表单的实例传递给已实现的回调类,因此,在调用Main方法时,您可以访问屏幕上显示的确切实例。

其次,您需要使用Invoke方法从另一个线程更新UI控件(到目前为止,我尚未使用CPLEX,但是我猜回调是从另一个线程调用的。这很常见)。 阅读此以获得更多信息。

完整的代码可能是:

public class FormOptimize : System.Windows.Forms.Form
{
    private callCplex()
    {
        //Misc code
        cplex.Use(new Cplex_ContinuousCallback(this)); // <-- passing `this`
        cplex.Solve()
        //Misc code
    }

    public void Update_OptimizeStatusbarPanel(String strText)
    {
        if (statusBarPanel_1.InvokeRequired)
            statusBarPanel_1.Invoke(Action<string>(Update_OptimizeStatusbarPanel), strText);
        else
        {
            statusBarPanel_1.Text = strText;
            statusBar1.Refresh();
        }
    }

    internal class Cplex_ContinuousCallback : Cplex.ContinuousCallback
    {
        FormOptimize _formOptimize;
        public Cplex_ContinuousCallback(FormOptimize formOptimize)
        {
            this._formOptimize = formOptimize;
        }

        public override void Main()
        {
            //...
            _formOptimize.Update_OptimizeStatusbarPanel(String.Format("Running Optimization: {0} iterations ", Niterations));
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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