0

Please forgive my little knowledge!

I have the following class in HIDNewDeviceEventMonitor.cs:

public class HIDNewDeviceEventMonitor : IDisposable
{
    // used for monitoring plugging and unplugging of USB devices.
    private ManagementEventWatcher watcherAttach;

    public HIDNewDeviceEventMonitor()
    {
        // Catch USB HID plugged instance event watching
        watcherAttach = new ManagementEventWatcher();
        watcherAttach.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
        watcherAttach.Query = new WqlEventQuery(@"SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_PNPEntity' AND TargetInstance.DeviceID LIKE 'HID\\VID_04D8%'");
        watcherAttach.Start();
    }

    void watcher_EventArrived(object sender, EventArrivedEventArgs e)
    {
        Debug.WriteLine("my device is inserted..");
    }

    public void Dispose()
    {
        watcherAttach.Stop();
        watcherAttach.Dispose();
    }

    ~HIDNewDeviceEventMonitor()
    {
        this.Dispose();
    }
}

Now, how can I change this class to be able to add an event handler that the class can call from within watcher_EventArrived where someNewEvent is outside the class file, actually in the form.cs:

// code in the form
HIDNewDeviceEventMonitor ok = new HIDNewDeviceEventMonitor();
ok.Inserted += someNewEvent;  // <-- my problem, I don't know how to add an event to the class this way

private void someNewEvent()
{
    //Enumerate and add to listbox1
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    ok.Dispose();
}

I 've seen this thing with other classes, how can I make my class like that?

elekgeek
  • 33
  • 1
  • 13
  • 1
    possible duplicate of [How to add an event to a class](http://stackoverflow.com/questions/85137/how-to-add-an-event-to-a-class) – Sinatr Dec 03 '14 at 13:36

3 Answers3

2

Your Inserted event should look like this:

public event EventHandler Inserted;

You invoke it like this:

private void OnInserted()
{
    if (this.Inserted != null)
    {
        this.Inserted(this, EventArgs.Empty);
    }
}

The signature for the event handler is this:

void someNewEvent(object sender, EventArgs e)
{
    //
}

Then you should wrap that code in the constructor of the class:

HIDNewDeviceEventMonitor ok;

public ClassName()
{
   ok = new HIDNewDeviceEventMonitor();
   ok.Inserted += someNewEvent;  // <-- my problem
}

Declare the ok variable outside the constructor, and instantiate it inside. Then add the event handler.

Pro tip: You could use the generic EventHandler<T> if you need to supply a custom implementation of e.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • I think that's his question; how to create the `Inserted` event – Sjeijoet Dec 03 '14 at 13:34
  • I stated that this is my problem, I don't know how to correctly create an event inside the class that can be assigned to an instance of this class in this manner i.e. =+ because I want to hide watcher_EventArrived and still be able to call another event from it. – elekgeek Dec 03 '14 at 13:36
  • You forgot to mention how to invoke the event from `watcher_EventArrived` ;) – Sjeijoet Dec 03 '14 at 13:40
  • @ Patrick Hofman Why would I do that, for example, in "Windows Form Designer generated code" I can see that it is possible to write: `this.button1.Click += new System.EventHandler(this.button1_Click);` if I follow your answer, this aint right to be honest – elekgeek Dec 03 '14 at 13:42
  • @Patrick Hofman, I just want to add an event handler to my class, the event handler doesn't take any arguments, and call this event handler from within watcher_EventArrived, to do other tasks. I don't want to supply any arguments, nor I want to wrap the declaration in a new class.. – elekgeek Dec 03 '14 at 13:47
  • 1
    @elekgeek There's multiple ways to define events. `button1.Click = ButtonClicked;` is equivalent to `button1.Click = new System.EventHandler(this.ButtonClicked);`. The designer just chooses to write it that way. Needlessly wordy, but pointless to go back and correct. – Cameron Dec 03 '14 at 13:49
  • I don't see a new class, and an `EventHandler` has a specific signature. If you don't want that, use an `Action` and assign with `=`. – Patrick Hofman Dec 03 '14 at 13:49
  • I mean public ClassName() – elekgeek Dec 03 '14 at 14:00
  • @elekgeek: That is just the constructor from a class in your existing code, but I don't know the name of it (`in the form.cs`). You put code in the class where you had to add it to the constructor. – Patrick Hofman Dec 03 '14 at 14:01
  • What I am trying to say that if I do this as you say, the IDE complains that ok is a field and not a type, so I can't use ok.Inserted.. – elekgeek Dec 03 '14 at 14:04
  • @elekgeek: Not inside your class definition, yes, put it in a method. – Patrick Hofman Dec 03 '14 at 14:05
  • I got your point, `public Form1()` :- ) It works now, thanks – elekgeek Dec 03 '14 at 14:10
1

Simply put, you're trying to add events to your HIDNewDeviceMonitor class.

To do this, first you'll need to define a delegate.

public delegate void InsertedHandler;

Next, you'll need to define the event in your HIDNewDeviceMonitor class.

// Notice how the event uses the delegate that's been defined
//               v       
public event InsertedHandler Inserted;

Now you'll need something that "fires" the event, which could easily be put in your watcher_EventArrived method.

void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
    Debug.WriteLine("my device is inserted..");

    // Notice how we check the event handler for null.
    // If you don't, it could throw a NullReferenceException.
    // Irritating, but easy to debug.. Usually..
    if (Inserted != null)
        Inserted(); // Or whatever parameters you need.
}

We're all done with the HIDNewDeviceMonitor class.

Now whatever class that uses the HIDNewDeviceMonitor can use the EventHandler code that you provided.

However, it'll have to be the same delegate.

public class MyClass
{
  HIDNewDeviceMonitor monitor;
  public MyClass()
  {
    monitor = new HIDNewDeviceMonitor();
    monitor.Inserted += DeviceInserted;
  } 

  private void DeviceInserted() 
  { 
   // Execute code here
  }
}
Cameron
  • 2,574
  • 22
  • 37
  • thanks for your answer, but why do you want to create MyClass? I just want to `HIDNewDeviceEventMonitor ok = new HIDNewDeviceEventMonitor();` and be able to `ok.Insterted += someNewEvent;` strange that I have to wrap this inside a new class – elekgeek Dec 03 '14 at 13:56
  • BTW, if I use ok.Inserted, the IDE complains saying that ok is a field, not a type! – elekgeek Dec 03 '14 at 13:58
  • @elekgeek I added that `MyClass` as an example for something that's encapsulating the `HIDNewDeviceEventMonitor`. I assuming that you'll be using a WinForms Form to do the same. – Cameron Dec 03 '14 at 14:05
  • @elekgeek After looking at your provided code, you'll need to add your EventHandler subscription (aka `ok.Inserted += someNewEvent;`) within the constructor of your Form1. (It should be notated as `public Form1() { InitializeComponent(); // Maybe other code here }`) – Cameron Dec 03 '14 at 14:10
  • I got your point, `public Form1()` :- ) It works now, thanks for pointing out, I did not read your last comment till after i figured this my self, but really thanks for pointing it out :- ) – elekgeek Dec 03 '14 at 14:11
0

You need to do following in the HIDNewDeviceEventMonitor class:

1.) First define a public event inside the class like this-

public event EventHandler Inserted; 2.) Then fire this event within the code where you detect the changes in events. Like this-

if(Inserted != null) Inserted(this,null);

The if condition checks if the event is registered by any listener. It's fired in case it is. Hope this helps.

havish
  • 305
  • 1
  • 4
  • 11
  • Once I write ok.Inserted, the IDE complains about ok being a field, not a type.. my problem is that Inserted is not recognized as a member event of ok – elekgeek Dec 03 '14 at 14:01