Вопрос

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

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

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

Это было полезно?

Решение

Вам просто нужно добавить общедоступный метод для вызова события.Microsoft уже делает это для некоторых событий, таких как ВыполнитьНажмите для элементов управления, которые предоставляют Нажмите событие.

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();
}

Другие советы

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

Итак, вы можете изменить свой код, чтобы он выглядел так:

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

Затем вы можете вызвать событие извне класса следующим образом.

myCustomGUIElement.Click(sender,args);

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

myCustomGUIElement.Click = null;

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top