Можно ли подвергнуть события член-объекта класса внешним в .NET?

Скажем, у меня есть элемент управления пользователя в ASP.NET, содержащий кнопку:

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

Я могу выставить любое свойство кнопки снаружи, создав свойство, которое указывает на кнопку:

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

Итак, я могу сделать это, чтобы установить текст кнопки:

MyControl.SaveButtonText = "hello world";

Есть ли аналогичная конструкция, которую я могу использовать для отображения событий кнопки снаружи? Что-то вроде:

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

Ответы

Ответ 1

Вы можете сделать что-то подобное, да:

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

Обратите внимание, что есть недостаток в этом - аргумент "отправитель", предоставленный обработчикам событий, по-прежнему будет кнопкой сохранения, а не вашим контролем... это может быть не то, что ожидал абонент. Альтернативный подход заключается в том, чтобы подписаться один раз на кнопку "Сохранить клик":

public event EventHandler SaveButtonClick = delegate {};

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

Там тоже есть недостаток этого подхода... вы все время получаете ссылку от кнопки сохранения на "this", что может повлиять на сбор мусора. В основном ваш контроль не сможет быть собранным мусором до тех пор, пока кнопка сохранения не будет пригодна для сбора мусора. В этом случае я очень сомневаюсь, что это проблема, но об этом стоит знать.

Ответ 2

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