C#从程序线程更新表单(richTextBox和toolStripStatusLabel)

时间:2012-11-08 01:18:44

标签: c# winforms

我正在尝试使用控制台应用程序并为它构建一个gui。我已经掌握了GUI的主要功能,并将控制台应用程序文件添加到我的新项目中。我更改了文件的命名空间以匹配winform应用程序的命名空间,并将控制台应用程序的主要功能移动到Program类中,将其定义为从表单获取CSV路径参数的函数。

所以它似乎正在运行程序,但我无法让表单更新。我想将一些Console.WriteLine()函数写入toolStripStatusLabel,将其他函数写入richTextBox。

我是C#的新手,主要的程序不是由我编写的,但我试图在它上面构建。

Program.cs的

Form1 Frm1 = new Form1();
Frm1.UpdateStatusBar("Sorted jobs by EDD....");
Frm1.Refresh();

Form1.cs的

public void UpdateStatusBar(string status)
{
    Form1 Frm1 = new Form1();
    Frm1.toolStripStatusLabel1.Text = status;  
}

Pastebin Program.cs 见第92行。

Pastebin Form1.cs 见第88行。

2 个答案:

答案 0 :(得分:1)

我认为,问题在于:您在尝试UpdateStatusBar()时尝试创建新的Form1。

您可以通过以下方式解决此问题:

public void UpdateStatusBar(string status)
{    
    this.toolStripStatusLabel1.Text = status;  
}

答案 1 :(得分:1)

正如@Thinhbk所说,每次想要更新工具条时创建一个新的Form1都不是可行的方法。您遇到的另一个问题是所有处理都在同一个线程中运行(我查看了您在Pastebin上发布的内容),这意味着无论如何您都不会看到进度更新。

为了实现这一点,我首先修改了public void AX1Program(string path)方法的签名:

public void AX1Program(Form1 form1, ManualResetEvent resetEvent, string path)

传递表单意味着我们可以访问UpdateStatusBar方法,resetEvent用于表示线程何时完成。 AX1Program的正文改为:

try
{
    ...
    //Do work as per normal
    ...
    form1.UpdateStatusBar("some new status");
}
catch (Exception)
{
    //Any exception handling/logging you may need.
}
finally
{
    //Indicate that we are done.
    resetEvent.Set();
}

现在,要调用AX1Program方法,您目前有一些代码(它位于Writebutton_Click方法的几个位置):

Program Pgm1 = new Program();
Pgm1.AX1Program(CSVtextBox.Text);

我们想要异步调用它,所以我们改为:

RunAX1Program(CSVtextBox.Text);

调用以下两种方法:

private void RunAX1Program(string text)
{
    ManualResetEvent resetEvent = new ManualResetEvent(false);
    ThreadPool.QueueUserWorkItem(RunAX1ProgramDelegate,
        new object[] { resetEvent, text });
}

private void RunAX1ProgramDelegate(object state)
{
    object[] stateArray = (object[])state;
    ManualResetEvent resetEvent = (ManualResetEvent)stateArray[0];
    string text = (string)stateArray[1];

    Program program = new Program();
    program.AX1Program(this, resetEvent, text);
    //Wait until the event is signalled from AX1Program.
    resetEvent.WaitOne();
}

因为我们现在想要从另一个线程更新工具条,所以UpdateStatusBar方法需要看起来像这样,以便我们可以安全地修改控件:

public void UpdateStatusBar(string status)
{
    if (this.InvokeRequired)
    {
        this.BeginInvoke((MethodInvoker)delegate
        {
            UpdateStatusBar(status);
        });
    }
    else
    {
        toolStripStatusLabel1.Text = status;
    }
}

然后,您可以使用类似的模式更新富文本框。