1

コンソール アプリケーションを取得して、そのための GUI を構築しようとしています。GUI の主な機能が動作し、コンソール アプリケーション ファイルを新しいプロジェクトに追加しました。ファイルの名前空間を winform アプリケーションの名前空間と一致するように変更し、コンソール アプリケーションのメイン関数を Program クラスに移動して、フォームから取得する CSV パス引数を取る関数として定義しました。

そのため、プログラムが機能しているように見えますが、フォームを更新するのに問題があります。toolStripStatusLabel に書き込みたい Console.WriteLine() 関数と、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 行目を参照してください。

4

2 に答える 2

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

これは、次の2つのメソッドを呼び出します。

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

次に、同様のパターンを使用してリッチテキストボックスを更新できます。

于 2012-11-08T02:43:03.943 に答える
1

問題は、UpdateStatusBar() を試行するたびに新しい Form1 を作成しようとしているということです。

これは次の方法で修正できます。

public void UpdateStatusBar(string status)
{    
    this.toolStripStatusLabel1.Text = status;  
}
于 2012-11-08T02:07:55.110 に答える