Вызывать события C # извне класса-владельца?
18338 просмотра
4 ответа
Возможно ли при любых обстоятельствах добиться этого?
Мои нынешние обстоятельства таковы:
public class CustomForm : Form
{
public class CustomGUIElement
{
...
public event MouseEventHandler Click;
// etc, and so forth.
...
}
private List<CustomGUIElement> _elements;
...
public void CustomForm_Click(object sender, MouseEventArgs e)
{
// we might want to call one of the _elements[n].Click in here
// but we can't because we aren't in the same class.
}
}
Моей первой мыслью было иметь функцию, похожую на:
internal enum GUIElementHandlers { Click, ... }
internal void CustomGUIElement::CallHandler(GUIElementHandler h, object[] args) {
switch (h) {
case Click:
this.Click(this, (EventArgs)args[0]);
break;
... // etc and so forth
}
}
Это ужасно уродливый клуг, но он должен сработать ... Хотя должно быть более элегантное решение? Библиотека .NET делает это все время с обработчиками сообщений и вызывающими событиями в Control. У кого-нибудь еще есть другие / лучшие идеи?
Автор: Matthew Scharley Источник Размещён: 12.07.2019 03:34Ответы (4)
25 плюса
Вам просто нужно добавить публичный метод для вызова события. Microsoft уже делает это для некоторых событий, таких как PerformClick для элементов управления, которые предоставляют событие Click .
public class CustomGUIElement
{
public void PerformClick()
{
OnClick(EventArgs.Empty);
}
protected virtual void OnClick(EventArgs e)
{
if (Click != null)
Click(this, e);
}
}
Затем вы должны сделать следующее внутри вашего примера обработчика событий ...
public void CustomForm_Click(object sender, MouseEventArgs e)
{
_elements[0].PerformClick();
}
Автор: Phil Wright
Размещён: 20.09.2008 11:52
8 плюса
Ключевое слово события в c # изменяет объявление делегата. Он предотвращает прямое назначение делегату (вы можете использовать только + = и - = для события) и предотвращает вызов делегата извне класса.
Таким образом, вы можете изменить свой код так:
public class CustomGUIElement
{
...
public MouseEventHandler Click;
// etc, and so forth.
...
}
Затем вы можете вызвать событие извне класса, как это.
myCustomGUIElement.Click(sender,args);
Недостатком является то, что код, использующий класс, может очень легко перезаписать любые зарегистрированные обработчики с помощью кода, подобного следующему:
myCustomGUIElement.Click = null;
что недопустимо, если делегат Click объявлен как событие.
Автор: Lee Размещён: 21.09.2008 08:561 плюс
Вы действительно должны обернуть код, который вы хотите иметь возможность выполнять извне в методе. Затем этот метод может делать то, что будет делать ваше событие - и это событие также будет вызывать этот метод.
Автор: Per Hornshøj-Schierbeck Размещён: 20.09.2008 11:520 плюса
Вы можете значительно сократить код, предложенный в принятом ответе, используя современную синтаксическую возможность .NET Framework:
public event Action<int> RecipeSelected;
public void RaiseRecpeSelected(int recipe) => RecipeSelected?.Invoke(recipe);
Автор: Larry
Размещён: 12.07.2019 12:33
Вопросы из категории :
- c# Преобразовать десятичную в двойную?
- c# Как рассчитать чей-то возраст в C #?
- c# Как вы сортируете словарь по значению?
- c# В чем разница между int и Integer в Java и C #?
- c# Как создать новый экземпляр объекта из Типа
- c# Datatable против Dataset
- events Каковы различия между делегатами и событиями?
- events Вызывать события C # извне класса-владельца?
- events Как мне обработать событие закрытия окна в Tkinter?
- events Зачем использовать EventArgs.Empty вместо null?
- events Event binding on dynamically created elements?
- events Вызывать события C # с помощью метода расширения - это плохо?
- inheritance Предпочитаете композицию наследству?
- inheritance Хорошие причины запретить наследование в Java?
- inheritance Что «супер» делает в Python?
- inheritance Наследование Python - как отключить функцию
- inheritance Переопределить метод с помощью общих параметров в Java?