2016-09-14 10 views
1

私はC#と一般的なプログラミングを習得しようとしており、問題が発生しました。私は答えを検索しようとしましたが、失敗しました。別の話題を複製しているとすみませます。デリゲートとイベントの使用方法は?

フォームには1つのウィンドウフォーム(Form1)、外部クラス(Class1)、ボタンおよびラベルがあります。 このクラスは簡単なファイルシュレッダーで、ボタンをクリックすると開始されます。 Label1.textは外部クラスから更新し、現在どのファイルが細断処理されているかを表示する必要があります。

私は、デリゲートとイベントを使って正しく動作させる必要があることを知りましたが、正しく使用する方法はわかりません。ここ コード:

//Form1 
    private async void button2_Click(object sender, EventArgs e) 
    { 
    var task = new Task(() => 
    { 
    check = true; 
    bool success = FileUtilities.Shred(textBox1.Text); 
    }); 
    task.Start(); 
    public void ChangeName(string text) 
    { 
    label3.Text = text; 
    } 

    //Class1 
    public static bool ShredFile(string filePath, bool shouldDelete = true) 
    { 
    bool success = true; 
    try 
    { 
    FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Write); 
    //Label1.text = filePath; - should be like that. 

私はプロパティにアクセスするためにpublic void ChangeNameを使用しようとしましたが、それはうまくいきませんでした。私はデリゲート、イベント、そしてどこにこのイベントを購読するのかを理解できません。

更新日:私は問題が何かを発見しました。私のプログラムにはいくつかのスレッドがあり、私のクラスを通してフォームのラベルにアクセスできませんでした。私はコールバックを使用しなければならず、その後、サブスクリプションとイベントは完全に機能しました。ありがとう、Thorsten Dittmar、正しい方法を示しています。

+2

デリゲートのドキュメントをご覧ください。 http://stackoverflow.com/documentation/c%23/1194/delegates#t=201609141320451060485 – Jacobr365

答えて

0

実際にあなたが望むものを達成するための方法はいくつかあります。私は次のようにして実装するのが最も簡単で、コールバックは必要ありません;-)

基本的な考え方は次のとおりです。UIの更新をUIを維持するクラスに任せてください。他のすべてはツールであり、UIがあるかどうかにかかわらず、を知っている必要はありません。

ファイルをシュレッダーがトリガーされ、あなたのUIのコード内のポイントを持っている場合は、次の3つの手順を実行します。

  1. をあなたのUIを更新し、例えば細断されているファイルのファイル名(UIクラス)
  2. を表示
  3. 細断処理ファイル(ツールクラス)
  4. 破砕操作のショーの成功または失敗(UIクラス)

参照してください?

  • しかし、あなたの質問には、実際にイベントを作成し、使用する方法だったので....

    は、一般的にイベントが送信側の2つの部分から構成され:-)イベントはありませんevent

  • examplため、

あなたはこのようにそれらの両方を宣言するイベントを発生させるための方法e。

public class EventSender 
{ 
    public event EventHandler<EventArgsType> MyEvent; 

    protected void OnMyEvent(...) 
    { 
     if (MyEvent != null) 
      MyEvent(this, new EventArgsType(...)); 
    } 
} 

EventArgsTypeを使用すると、受信機に送信者からの情報を渡すために使用することができますEventArgsのサブクラスです。例:

public class EventSender 
{ 
    public class EventArgsType : EventArgs 
    { 
     public EventArgsType(string fileName) : base() 
     { 
      FileName = fileName; 
     } 

     public string FileName 
     { 
      get; 
      private set; 
     } 
    } 

    public event EventHandler<EventArgsType> MyEvent; 

    protected void OnMyEvent(string filename) 
    { 
     if (MyEvent != null) 
      MyEvent(this, new EventArgsType(filename)); 
    } 
} 

イベントが発生しなければならないときはいつでも、EventSenderクラス内からOnMyEvent方法を呼び出すのに十分です。

受信者はイベントに自身を添付し、イベントが発生するたびにメソッドが呼び出される必要があります。例

public class Receiver 
{ 
    private EventSender _sender; 

    public Receiver() 
    { 
     _sender = new EventSender(); 
     _sender.MyEvent += HandleMyEvent; 
    } 

    private void HandleMyEvent(object sender, EventSender.EventArgsType e) 
    { 
     // Do something with e.FileName 
    } 
} 

あなたのケースではどうしますか? nonstaticクラスFileShredderを作成し、例のような1つ以上のイベントを実装し、nonstaticというファイルを細断する方法があります。

UIでタスクを開始する前に、このクラスのインスタンスを作成し、必要なイベントハンドラをアタッチしてから、そのインスタンスを使用してファイルを破棄します。 UIクラスのイベントハンドラで、ラベルや内容を変更します。

+0

'FileStream fs = new FileStream(filePath、FileMode.Open、FileAccess.Write)の後に' OnMyEvent(filePath) 'を追加しました。 '私のツールクラスでは、すべての時間nullを返します。イベントを起こすことはできません。 –

+0

まず最初にサンプルプロジェクトを作成し、どのように動作するかを理解し、学習した内容を現在のプロジェクトに統合しようとしていますか?また、あなたの例では、すべてのことをすることにも意味がありません。タスクを開始する前に、ラベルのテキストを 'TextBox'のファイル名に設定するだけです。 Done- –

+0

これは私のサンプルプロジェクトです) 'textBox'は細断するファイルではなく、場所です。そのテストフォルダには1k個のファイルがあり、ツールクラスだけがこれらのパスを認識しています。しかし、あなたは正しいです、私はそれを最初に理解する必要があります。そのような詳細な答えをありがとう。 –

関連する問題