我有一个关于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?
谢谢。
答案 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();
}