2010-02-22 5 views
5

Piszę bibliotekę klas, która będzie używana przez inne aplikacje. Piszę to w C# .NET. Mam problem z wyzwalaniem zdarzeń na różnych klasach. Oto, co trzeba zrobić ...Jak wyzwalać zdarzenie na różnych zajęciach?

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

} 

Następnie w aplikacji, która korzysta z biblioteki klasy będzie to zrobić ...

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

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

Odpowiedz

1

Myślę, że powinieneś zmienić swoje spojrzenie na to, jak działają wydarzenia. OtherClass powinien "posiadać" wydarzenie i wyzwolić go. ClassLibrary lub ClientApplication (w zależności od tego, co wybierzesz) "nasłuchuje" zdarzenia przez "zasubskrybowanie" go i wykonuje określone działanie, gdy wystąpi to zdarzenie.

Jak zaimplementować to:

public class ClassLibrary 
{ 
    public OtherClass myOtherCl; 

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

wyzwalania zdarzenia w klasie, gdzie logicznie dzieje, gdzie jest wykrywany.

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

} 

Wreszcie, kto musi słuchać zdarzenie musi mieć dostęp do instancji klasy posiadającej wydarzenie, dlatego myOtherCl upubliczniono w tym przykładzie.

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... 
    } 
} 
+0

Na marginesie, upewnij się, że skopiowałeś program obsługi zdarzeń przed uruchomieniem go dla bezpieczeństwa wątków: 'var ev = DeviceAtached; if (ev! = null) ev(); ' – Tanzelax

8

Nie można tego zrobić. Zdarzenia mogą być wywoływane tylko z klasy, która deklaruje zdarzenie.

Zazwyczaj by dodać metodę na klasy, aby podnieść zdarzenia i wywołać metodę:

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

Następnie, w drugim kodzie, że po prostu zadzwonić myCL.NotifyDeviceAttached();

+0

Czy narzędzie NotifyDeviceAttached musi być statyczne? W przeciwnym razie jak mogę odwołać się do instancji ClassLibrary z OtherClass, gdy OtherClass go nie utworzył? – PICyourBrain

+0

Musisz podać formularz we właściwej instancji. W przeciwnym razie możesz ustawić opcję NotifyDeviceAttached static, ale musisz również uczynić swój event event statycznym wydarzeniem ... To wszystko jest kwestią projektu. –

1

Event procedury obsługi mogą być wywoływane tylko bezpośrednio przez grupę, która je zadeklarowała. Jeśli trzeba zadzwonić ClassLibrary.DeviceAttached spoza tej klasy, trzeba dodać metodę Narzędzie jak następuje:

public void OnDeviceAttached() 
{ 
    DeviceAttached(); 
} 
+0

hmmm ok. Czy zdarzenie może zostać przekazane klasie jako odniesienie i nazwane w ten sposób? – PICyourBrain

+0

@Jordan S: Nie. Projektanci C# celowo zrobili to tak, że nie można podnieść zdarzenia z innej klasy, nawet podklasy. MUSISZ zrobić to od klasy, która zadeklarowała wydarzenie. –

+0

Czy funkcja OnDeviceAttached musi być statyczna? W przeciwnym razie jak mogę odwołać się do instancji ClassLibrary z OtherClass, gdy OtherClass go nie utworzył? – PICyourBrain

1

Nie może chcieć wykorzystać zdarzenie w ogóle tutaj. Jest to nadmierne uproszczenie, ale generalnie zdarzenie jest czymś podniesionym przez element potomny, kiedy musi coś przekazać swojemu rodzicowi. W twoim przypadku (wywnioskowałem z twojego kodu), twój formularz nasłuchuje konkretnej wiadomości (kiedy urządzenie jest podłączone?), A kiedy dostrzeże tę wiadomość, musi o tym powiedzieć myCL. W tym celu wystarczy, że utworzysz metodę pod numerem ClassLibrary i wyślesz ją ze swojego formularza.

+0

Mój przykład opuszcza wiele szczegółów. OtherClass w rzeczywistości nie jest widoczną formą, po prostu dziedziczy po formularzu, dzięki czemu można go wykorzystać do przechwytywania komunikatów systemu Windows, gdy urządzenie USB jest podłączone/odebrane ... Wiem, że jest to mylące. – PICyourBrain