0

クラスとフォームがあります。このクラスは、イベントが発生したときにいくつかのプロセスを実行し、値をフォームに戻して表示することのみを目的としています。値をフォームに戻すのに問題があります。たとえば、クラスに次のコードがありますprint

  public class PrintClass : Form1
{

    public void printEventHandler(object sender, EventArgs e)
    {

        string text = "Process Completed";
        append_Tbox(text);

    }

}

そして、テキストを表示するための form1 のメソッド:

  public void append_Tbox(string s)
    {

        TboxPrint.AppendText(s);
    }

ただし、何も表示されません。何か問題があると思いますが、わかりません。クラスからフォームに値を渡す最速の方法は何ですか?

4

3 に答える 3

1

まず、処理クラスを拡張しないでくださいForm1。これは、既存のフォームのメソッドにアクセスできるという幻想を与えていますが、それはあなたが思っていることをしていません。これを行うと、まったく新しいフォームが作成され、表示されなくなります。そのフォームにはすべてのインスタンスフィールドの独自のセットがあるため、メインフォームのコントロールにアクセスすることはありません。これが機能する(そして機能しない)としても、適切に設計されたソリューションではありません。

これを行う適切な方法は、実際にははるかに簡単です。他のクラスがそのメソッドから値を返すようにする必要があります。

public class PrintClass
{
    public string DoWork()
    {
        Thread.Sleep(2000);//placeholder for real work.
        return "Process Completed";
    }
}

これで、メインフォームはそのメソッドを呼び出して、戻り値をテキストボックスに追加できます。

これを行うと、まったく別の問題が発生します。UIスレッドで作業を行うと、作業中にそのUIスレッドがブロックされ、フォームが再描画されたり、その他のイベントが処理されたりするのを防ぐことができます。バックグラウンドスレッドで作業を行ってから、UIスレッドにマーシャリングして、結果でUIを更新する必要があります。これを行うにはいくつかの方法がありますが、C#5.0を使用している場合は、使用awaitするのがはるかに簡単です。

public class Form1 : Form
{
    private void SomeEventHandler(object sender, EventArgs args)
    {
        string result = await Task.Run(()=>new PrintClass().DoWork());
        TboxPrint.AppendText(result);
    }
}

C#4.0ソリューションが必要な場合はContinueWith、を使用できます。これは、多かれ少なかれ上記に変換されるものですが、構文はそれほどきれいではありません。

public class Form1 : Form
{
    private void SomeEventHandler(object sender, EventArgs args)
    {
        Task.Factory.StartNew(()=>new PrintClass().DoWork())
            .ContinueWith(t => TboxPrint.AppendText(t.Result)
                , CancellationToken.None
                , TaskContinuationOptions.None
                , TaskScheduler.FromCurrentSynchronizationContext());
    }
}
于 2013-02-25T06:50:11.753 に答える
0

メインフォームでデリゲートを作成しました

 public delegate void LoginDelegate(string s);

 public partial class AirLineReservationMDI : Form
    {
        LoginDelegate loginAirLineDelegate;

    }

loginAirLineDelegate = new LoginDelegate(DisableToolStripMenuItems);


 public void DisableToolStripMenuItems(string s)
        {
           this.viewToolStripMenuItem.Visible = true;
            this.bookingToolStripMenuItem.Visible = true;
            this.existingUserToolStripMenuItem.Visible = false;
            this.newUserToolStripMenuItem.Visible = false;
            this.toolStripStatusUserID.Text = "USerID :- "+s;             
           this.LoginUserId = s;
        }

別のクラスでは、(私はこのクラスにdelageteオブジェクトを渡しました)Delegateを解雇しました

  logDelegate(textBoxUserName.Text);
于 2013-02-25T06:39:18.080 に答える
0

Action<T>問題を解決するためにデリゲートを使用しました。ここにコードがあり、正常に動作します。

 class PrintClass 
{
    public Action<string> DisplayDelegate;


    public void printEventHandler(object sender, EventArgs e)
    {
        string text = "Event Handled, and text value is passed";

        var copy = DisplayDelegate;

        if (copy != null)
        {
           copy(text);
        }
    }

}

そして `Form1.cs' で:

 private void Form1_Load(object sender, EventArgs e)
    {
        PrintClass p = new PrintClass();
        BtnPrint.Click += p.printEventHandler;

        //subscrite the displayevent method to action delegate
        p.DisplayDelegate += DisplayEvent;

    }


    public void DisplayEvent(string s)
    {

        Invoke(new Action(() => TboxPrint.AppendText(s)));
    }

そのため、「イベントが処理され、テキスト値が渡されました」というテキストがテキストボックスに表示されます。

それが効率的な方法かどうかはわかりません。みんなありがとう。

于 2013-02-27T04:01:16.523 に答える