是否可以在.NET中向外部公开类的成员对象的事件?

时间:2022-02-19 11:11:40

Say I have a User Control in ASP.NET that contains a button:

假设我在ASP.NET中有一个包含按钮的用户控件:

public class MyUserControl : UserControl {
    private Button btnSave = new Button();
}

I can expose any property of the button to the outside by making a property that points at the button:

我可以通过创建指向按钮的属性将按钮的任何属性暴露给外部:

public string SaveButtonText { 
    get { return btnSave.Text; } 
    set { btnSave.Text = value; } 
}

So then I can do this to set the button's text:

那么我可以这样设置按钮的文本:

MyControl.SaveButtonText = "hello world";

Is there a similar construct I can use to expose the button's events to the outside as well? Something like:

是否有类似的构造我可以用来向外部公开按钮的事件?就像是:

public event SaveButtonClick { return btnSave.OnClick; }
...
MyControl.SaveButtonClick += new EventHandler(...);

2 个解决方案

#1


23  

You can do something like that, yes:

你可以这样做,是的:

public event EventHandler SaveButtonClick
{
    add { btnSave.Click += value; }
    remove { btnSave.Click -= value; }
}

Note however that there's one downside to this - the "sender" argument supplied to the event handlers will still be the save button rather than your control... that may not be what the subscriber expected. An alternative approach is to subscribe once to the save button's click handler yourself:

但请注意,这有一个缺点 - 提供给事件处理程序的“sender”参数仍然是保存按钮而不是您的控件......这可能不是订阅者所期望的。另一种方法是自己订阅一次保存按钮的点击处理程序:

public event EventHandler SaveButtonClick = delegate {};

private void OnSaveButtonClicked(object sender, EventArgs e)
{
    // Replace the original sender with "this"
    SaveButtonClick(this, e);
}
...
btnSave.Click += OnSaveButtonClicked();

There's a downside to this approach too... you end up having a reference from the save button to "this" all the time, which may have an impact on garbage collection. Basically your control won't be able to be garbage collected until the save button is also eligible for garbage collection. In this case I very much doubt that it's an issue, but it's worth being aware of.

这种方法也存在缺点......你最终会从保存按钮到“this”的引用,这可能会对垃圾收集产生影响。基本上,在保存按钮也符合垃圾回收条件之前,您的控件将无法进行垃圾回收。在这种情况下,我非常怀疑这是一个问题,但值得注意。

#2


5  

    public event EventHandler SaveButtonClick {
        add { btnSave.Click += new EventHandler (value); }
        remove { btnSave.Click-= new EventHandler (value); }
    }

#1


23  

You can do something like that, yes:

你可以这样做,是的:

public event EventHandler SaveButtonClick
{
    add { btnSave.Click += value; }
    remove { btnSave.Click -= value; }
}

Note however that there's one downside to this - the "sender" argument supplied to the event handlers will still be the save button rather than your control... that may not be what the subscriber expected. An alternative approach is to subscribe once to the save button's click handler yourself:

但请注意,这有一个缺点 - 提供给事件处理程序的“sender”参数仍然是保存按钮而不是您的控件......这可能不是订阅者所期望的。另一种方法是自己订阅一次保存按钮的点击处理程序:

public event EventHandler SaveButtonClick = delegate {};

private void OnSaveButtonClicked(object sender, EventArgs e)
{
    // Replace the original sender with "this"
    SaveButtonClick(this, e);
}
...
btnSave.Click += OnSaveButtonClicked();

There's a downside to this approach too... you end up having a reference from the save button to "this" all the time, which may have an impact on garbage collection. Basically your control won't be able to be garbage collected until the save button is also eligible for garbage collection. In this case I very much doubt that it's an issue, but it's worth being aware of.

这种方法也存在缺点......你最终会从保存按钮到“this”的引用,这可能会对垃圾收集产生影响。基本上,在保存按钮也符合垃圾回收条件之前,您的控件将无法进行垃圾回收。在这种情况下,我非常怀疑这是一个问题,但值得注意。

#2


5  

    public event EventHandler SaveButtonClick {
        add { btnSave.Click += new EventHandler (value); }
        remove { btnSave.Click-= new EventHandler (value); }
    }