在表单之间使用Reference EventHandler

时间:2016-03-16 09:15:53

标签: c# .net

我有一个关于EventHandler的问题(在这种情况下,我想创建一个只有progressBar的非常简单的Form)。

我有两种形式:

@ChecksPermission
public boolean hasMapLocationPermissions(Activity activity) {
  return // my checking logic..
}

}

2°:

public partial class Form1 : Form {

  public Form1() {
     InitializeComponent();
  }
  /// <summary>
  /// Event to notify change
  /// </summary>
  private EventHandler progress;

  private void button1_Click(object sender, EventArgs e) {

     Form2 BarForm = new Form2() { SomeEvent = progress};// <- When i assign handler in Form2 class progress in Form1 is always null
     BarForm.Show();

     BarForm.sethandler(ref progress);// <- If i don't insert this function with "ref" progress is null.

     for (int i = 0; i < 1000000; i++) {
        if (progress != null)
           progress(this, new EventArgs());
     }
  }

}

好吧,如果我删除“DarForm.sethandler(ref progress)”行,则此类中的处理程序为null,尽管在Form2_Load中我设置了从Form1传递的处理程序。 我在命令行中想到了

public partial class Form2 : Form {

  public EventHandler SomeEvent{ get; set; }

  public Form2() {
     InitializeComponent();
  }

  private void Form2_Load(object sender, EventArgs e) {

     this.progressBar1.Maximum = 1000000;
     this.progressBar1.Minimum = 0;

     SomeEvent += new EventHandler(new Action<object, EventArgs>((s, ee) => {
        this.progressBar1.PerformStep();
     }));// <- Here i assign handler but ONLY in this Form i have a SomeEvent != null

  }
  /// <summary>
  /// without this function the Event Handler in other form remain always null
  /// </summary>
  /// <param name="h"></param>
  public void sethandler( ref EventHandler h){           
        h += new EventHandler(new Action<object, EventArgs>((s, ee) => {
        this.progressBar1.PerformStep();
     }));

  }

我已将Form1中“progress”的引用分配给Form2中的“SomeEvent”。

现在,要设置一个类的EventHandler,我必须使用ref KeyWord?

谢谢。

2 个答案:

答案 0 :(得分:0)

您需要在子窗体中侦听主窗体的事件,而不是传递事件处理程序的引用。不要将事件处理程序的引用传递给其他表单。而是传递Form1引用,如下面链接中所述 - Listening to Events in Main Form from Another Form in C#。然后在form2中订阅Form1.Progress并处理事件。

修改 您不应该像普通对象一样传递EventHandler的引用,因为它们不是作为引用传递的,而是用作发布者订阅者。如果您热衷于不按原样传递Form1对象,则可以将事件处理程序部分抽象为接口并仅传递该接口。

E.g。

interface IProgressHandler
{
  EventHandler Progress{get;set;}
}

Form1 : IProgressHandler
{
Form2 BarForm = new Form2(this) ;
}

Form2
{
   IProgressHandler  _progressHandler
   public Form2(IProgressHandler progressHandler) 
   {
     _progressHandler = progressHandler;
     _progressHandler.Progress+=(s, ee) => { this.progressBar1.PerformStep() };
     InitializeComponent();
   }
}

答案 1 :(得分:0)

这很干净

Form1中:

public EventHandler SomeEvent { get; set; }
public Form1()
{
    InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
    Form2 f = new Form2();
    this.SomeEvent += new EventHandler(f.IncProgress);
    f.Show();
    for (int i = 0; i < 1000000; i++)
    {
        if (SomeEvent != null)
            SomeEvent(this, new EventArgs());
    }
    f.Close();

}

窗体2:

   public Form2()
    {
        InitializeComponent();
        this.progressBar1.Maximum = 1000000;
        this.progressBar1.Minimum = 0;
    }

    public void IncProgress(object Sender, EventArgs e)
    {
        this.progressBar1.PerformStep();
    }