Вопрос по inheritance, events, c# – Вызывать события C # извне класса-владельца?

13

Возможно ли при любых обстоятельствах добиться этого?

Мои нынешние обстоятельства таковы:

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 делает это все время с обработчиками сообщений и событиями вызова в элементах управления. У кого-нибудь еще есть другие / лучшие идеи?

Ваш Ответ

3   ответа
8

Ключевое слово события в c # изменяет объявление делегата. Он предотвращает прямое назначение делегату (вы можете использовать только + = и - = для события) и предотвращает вызов делегата извне класса.

Таким образом, вы можете изменить свой код так:

public class CustomGUIElement
{
...
    public MouseEventHandler Click;
    // etc, and so forth.
...
}

Затем вы можете вызвать событие извне класса, как это.

myCustomGUIElement.Click(sender,args);

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

myCustomGUIElement.Click = null;

что недопустимо, если делегат Click объявлен как событие.

Error: User Rate Limit Exceeded Matthew Scharley
Error: User Rate Limit Exceeded
1

Вы действительно должны обернуть код, который вы хотите иметь возможность выполнять извне в методе. Затем этот метод может делать то, что будет делать ваше событие - и это событие также будет вызывать этот метод.

Error: User Rate Limit Exceeded Matthew Scharley
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();
}
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Matthew Scharley
Error: User Rate Limit Exceeded

Похожие вопросы