1

テキストボックスにテキストを書き込むための一連のイベントを開始するには、プログラムでクラスを作成する必要があります。クラスがフォームについて知っているべきではないことを私は知っています。どうやってするか?クラスを別のスレッドにインストールするという事実を考慮してください。

クラスを接続するインターフェイスを作成し、フォームのメソッドをrefパラメーターで作成しようとしました。

*更新: * 皆さんは私を誤解しています - 私はプログラミング以外のイベントについて話していました。必要なのは、別のクラスからテキストボックスにテキストを追加することだけです。「一連のイベント」を追加して、同様の質問から定義しました。それらの中で、クラスからテキストを直接変更しようとしました。ごめん。

4

2 に答える 2

4

ここには 2 つの可能性のあるオプションがあります。

「他のクラス」は、作業が「完了」するとすぐにテキストボックスを更新する必要があります。この場合、フォーム、テキストボックス、インターフェイスなど、何も知らないはずです。値を返すだけで、フォームがその戻り値を使用してテキストボックスを設定したり、何でもできるようにする必要があります。

ほとんどの状況では、これがやりたいことであり、この種の問題を解決するための最も簡単で効果的な手段です。必要がない場合は、より複雑なものを使用しないでください。

タスクが「完了」したときに情報が発生せず、代わりに定期的な間隔で発生する場合は、インターフェイスでProgressクラスを使用できます。IProgress

インスタンスをForm作成します: Progress<string> progress = new Progress<string>();. そのインスタンスのイベント ハンドラーをフォームに添付します。インスタンスは現在の同期コンテキストを「キャプチャ」することに注意してくださいProgress。これは、UI スレッドで実行されることを巧妙に表現したものです。これは次のように実行できます。

progress.ProgressChanged += (_, data) => textBox1.Text = data;

次に、他のクラスにインスタンスを受け入れIProgress<string>させ、定期的に呼び出します。

progress.Report(someString);

Progressおよびの 4.5 より前の実装が必要な場合IProgressは、.NET 3.5+ でコンパイルおよび実行される実装を次に示します。

public interface IProgress<T>
{
    void Report(T data);
}

public class Progress<T> : IProgress<T>
{
    SynchronizationContext context;
    public Progress()
    {
        context = SynchronizationContext.Current
            ?? new SynchronizationContext();
    }

    public Progress(Action<T> action)
        : this()
    {
        ProgressReported += action;
    }

    public event Action<T> ProgressReported;

    void IProgress<T>.Report(T data)
    {
        var action = ProgressReported;
        if (action != null)
        {
            context.Post(arg => action((T)arg), data);
        }
    }
}
于 2013-02-08T20:46:52.787 に答える
2

アプリケーションについて十分に理解していない場合は、フォームによって処理されるクラスでイベントを呼び出す必要があることをお勧めします。何が起こるかは次のようになります。

  1. クラスにはイベントがあります。
  2. フォームが起動し、クラスをインスタンス化します。
  3. フォームはクラスのイベントにハンドラーを割り当てます。
  4. クラスは、フォームと通信する必要があるポイントに到達するまで、必要なことは何でも行います。
  5. クラスはイベントを発生させます。
  6. フォーム内のハンドラーが実行され、テキスト ボックスが変更されます。

したがって、クラスのコードにいくつかの定義を追加する必要があります。

public delegate void FinishedEventHandler(object sender, string ValueToReturn);
public event FinishedEventHandler Finished;

1 つ目は、イベントの署名を持つデリゲートです。慣例により、最初の引数は常にクラス自体のインスタンスへの参照であり、残りは返す値です。2つ目は実際の出来事です。

ここで、クラスが行うすべての処理を行う関数で、必要に応じてイベントを発生させる必要があります。

void DoSomething()
{
    .
    .
    .
    if(Finished!=null) Finished(this, "some value");
}

if 句は、誰かが実際にイベントを処理していることを確認するために使用されます。そうしないと、例外が発生する可能性があります。

では、フォームを見てみましょう。イベントを処理する関数を追加する必要があります。以前に定義したデリゲートと同じ署名が必要です。その関数内で、返された値に照らしてフォームに必要な変更を行います。

private void FinishedEventHandler(object sender, string ValueToReturn)
{
    TextBox1.Text = ValueToReturn;
}

これで、作成したすべての配管を使用する準備が整いました。最初にハンドラーをイベントに追加すると、クラスの処理関数を呼び出すことができます。

MyClass.Finished += FinishedEventHandler;
MyClass.DoSomething();

より詳細なチュートリアルは次のとおりです。

http://msdn.microsoft.com/en-us/library/aa645739(v=vs.71).aspx

于 2013-02-08T20:44:33.523 に答える