Как вы запускаете событие между классами? - PullRequest
5 голосов
/ 22 февраля 2010

Я пишу библиотеку классов, которая будет использоваться другими приложениями. Я пишу это в C # .NET. У меня проблема с запуском событий между классами. Вот что мне нужно сделать ...

public class ClassLibrary
{
    public event EventHandler DeviceAttached;

    public ClassLibrary()
    {
        // do some stuff
        OtherClass.Start();
    }
}

public class OtherClass : Form
{
    public Start()
    {
        // do things here to initialize receiving messages
    }

    protected override void WndProc (ref message m)
    {
       if (....)
       {
          // THIS IS WHERE I WANT TO TRIGGER THE DEVICE ATTACHED EVENT IN ClassLibrary
          // I can't seem to access the eventhandler here to trigger it.
          // How do I do it?

       }
       base.WndProc(ref m);
    }

}

Затем в приложении, которое использует библиотеку классов, я сделаю это ...

public class ClientApplication
{
    void main()
    {
       ClassLibrary myCL = new ClassLibrary();
       myCL.DeviceAttached += new EventHandler(myCl_deviceAttached);
    }

    void myCl_deviceAttached(object sender, EventArgs e)
    {
         //do stuff...
    }
}

Ответы [ 4 ]

8 голосов
/ 22 февраля 2010

Вы не можете сделать это. События могут быть вызваны только из класса, который объявляет событие.

Обычно вы добавляете метод в своем классе для вызова события и вызываете метод:

public class ClassLibrary 
{ 
    public event EventHandler DeviceAttached; 
    public void NotifyDeviceAttached()
    {
       // Do processing and raise event
     }

Затем в другом коде вы просто позвоните myCL.NotifyDeviceAttached();

1 голос
/ 23 февраля 2010

Я думаю, вы должны изменить свою точку зрения на то, как работают события. OtherClass должен «владеть» событием и запускать его. ClassLibrary или ClientApplication (в зависимости от того, что вы выберете) «слушает» событие, «подписавшись» на него, и выполняет определенное действие при возникновении этого события.

Как это реализовать:

public class ClassLibrary
{
    public OtherClass myOtherCl;

    public ClassLibrary()
    {
        myOtherCl= new OtherClass();
        myOtherCl.Start();
    }
}

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

public class OtherClass : Form
{
    public event EventHandler DeviceAttached;

    public Start()
    {
        // do things here to initialize receiving messages
    }

    protected override void WndProc (ref message m)
    {
       if (....)
       {
          OnDeviceAttach();
       }
       base.WndProc(ref m);
    }

        public void OnDeviceAttach()
        {
            if (DeviceAttached != null)
                DeviceAttached ();
        }

}

Наконец, тому, кому нужно прослушать событие, нужен доступ к экземпляру класса, содержащего событие, поэтому в этом примере myOtherCl был обнародован.

public class ClientApplication
{
    void main()
    {
       ClassLibrary myCL = new ClassLibrary();
       myCL.myOtherCl.DeviceAttached += new EventHandler(myCl_deviceAttached);
    }

    void myCl_deviceAttached(object sender, EventArgs e)
    {
         //do stuff...
    }
}
1 голос
/ 23 февраля 2010

Вы можете вообще не использовать событие здесь. Это упрощение, но, как правило, событие - это что-то, инициируемое дочерним компонентом, когда ему необходимо сообщить что-то своему родителю. В вашем случае (исходя из вашего кода) ваша форма прослушивает определенное сообщение (когда устройство подключено?), И когда оно обнаруживает это сообщение, оно должно сообщить myCL о нем. Для этого вместо этого вы просто должны создать метод в ClassLibrary и вызвать его из своей формы.

1 голос
/ 22 февраля 2010

Обработчики событий могут вызываться напрямую только тем классом, который их объявил. Если вам нужно вызвать ClassLibrary.DeviceAttached извне этого класса, вам нужно добавить служебный метод, подобный следующему:

public void OnDeviceAttached()
{
    DeviceAttached();
}
...