I have the following code with 3 different classes. I am trying to
Subscribe event from class B to method (event handler) defined in
class ControlSystem. All compiles fine, it works no problem but the event handler method is never triggered... What am I doing wrong?
namespace EventTest
{
public class ControlSystem : CrestronControlSystem
{
A myObject = new A();
public ControlSystem(): base()
{
Thread.MaxNumberOfUserThreads = 100;
// Subscribe Event
myObject.mySubObject.BEvent += HandleBEvent;
// Throw Event
myObject.mySubObject.ThrowEvent();
}
public override void InitializeSystem()
{
}
public void HandleBEvent(object sender, EventArgs args)
{
Console.WriteLine("Something happend to {0}", sender);
}
}
public class A
{
public B mySubObject;
public A()
{
mySubObject = new B();
}
}
public class B
{
public EventHandler BEvent;
public B(){}
public void ThrowEvent()
{
EventHandler handler = BEvent;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
}
Real code links below (it works with Embeded system so you won't be able to compile it). Idea is to have button press to trigger an event which could
alarm other UIs that something happend to it.
http://ideone.com/NJz2Ek
Thanks
You are missing the event keyword.
public event EventHandler BEvent;
is what needs to be there.
Related
I need to Raise an Event from another Class - i know that this is not possible - but I need a workaround for this.
For now Im doing the following
This is the class, which have to raise the event
internal class DataTransfer
{
public delegate void EventHandler(object sender, OnReaderCommonEventArgs e);
public event EventHandler _OnSerialNumber;
public event EventHandler _OnReaderType
Task DataHandler()
{
//Recieving-Data and Stuff
_OnSerialNumber(this, new OnReaderCommonEventArgs { SerialNumber = RFIDParser.ParseSerialNumber(data) });
_OnReaderType(this, new OnReaderCommonEventArgs { ReaderType = RFIDParser.ParseReaderType(data) });
}
}
And in the Main-Class, which will be used by the user. So the user can only subscribe to the event from this class-object:
public partial class PUR_100U
{
public delegate void EventHandler(object sender, OnReaderCommonEventArgs e);
public event EventHandler OnSerialNumber;
public event EventHandler OnReaderType;
public PUR_100U(int portnumber)
{
dataTransfer = new DataTransfer(portnumber, GetIdentifierList());
dataTransfer._OnSerialNumber += dataTransfer__OnSerialNumber;
dataTransfer._OnReaderType += dataTransfer__OnReaderType;
}
void dataTransfer__OnSerialNumber(object sender, OnReaderCommonEventArgs e)
{
if (OnSerialNumber != null) { OnSerialNumber(this, new OnReaderCommonEventArgs { SerialNumber = e.SerialNumber }); }
}
void dataTransfer__OnReaderType(object sender, OnReaderCommonEventArgs e)
{
if (OnReaderType != null) { OnReaderType(this, new OnReaderCommonEventArgs { ReaderType = e.ReaderType }); }
}
}
Example of user-usage:
rfid = new PUR_100U(20);
rfid.OnSerialNumber += rfid_OnSerialNumber;
rfid.OnReaderType += rfid_OnReaderType;
Is there a better way of doing this?
I need to Raise an Event from another Class - i know that this is not possible - but I need a workaround for this.
That is rather trivial:
class Foo
{
public event EventHandler Fooed; //note, name is not OnFoo
public void FireFooed() => Fooed?.Invoke(this, new EventArgs);
}
And now, fire the event at will:
var foo = new Foo();
foo.FireFooed();
The question is, why do you want to do this? It seems like a really bad idea. Fooed should fire only and only if the preconditions inside Foo for it to fire are met; if you need Fooed to fire, then make the preconditions happen!
Firing Fooed at will if the conditions aren't met will break all other listeners, don't do that.
I have a class with an EventHandler for TimeChanged. A couple of instances of this class are created. In one of the instances of the class, the time can be changed. I would like all instances to react to the event of changed time.
Example:
public class MainClass
{
public MainClass()
{
}
public event EventHandler TimeChanged;
private virtual void OnTimeChanged()
{
EventHandler handler = TimeChanged;
if(handler != null)
{
handler(this, eventArgs.Empty);
}
}
}
public class AnotherClass
{
public AnotherClass()
{
MainClass _mainClass = new MainClass();
}
private void OnLoaded()
{
_mainClass.TimeChanged += HandleTimeChanged;
}
private void HandleTimeChanged
{
//Some stuff happens with new time, etc.
}
}
public class TimeClass
{
MainClass _class = new MainClass();
TimeSpan _timeValue;
private void ChangeTime()
{
// This is where the _timeValue is changed
// All instances of MainClass, subscribed to TimeChanged event to be notified with the new value selected.
}
}
So, basically when I change the time in TimeClass, which contains an instance of MainClass, I want to fire the TimeChanged event and all instances of MainClass (like in AnotherClass) should respond to the TimeChanged event to which they subscribed.
Hope this explains the situation. Any suggestions are welcome. Thanks.
I have a code which should notify a delegate in one of service classes on receiving an event:
public class TestClass : ParentClass
{
public event EventHandler<string> MyDelegate;
public override void OnAction(Context context, Intent intent)
{
var handler = MyDelegate;
if (handler != null)
{
handler(this, "test");
}
}
}
I instantiate it by:
private TestClass mytest= new TestClass ();
And then assign it in one of the functions:
mytest.MyDelegate+= (sender, info) => {
};
The delegate never gets called. I have stepped through with debugger and I see that delegate is being assigned, but the check inside a class is always null... Cant figure out whats the problem...
Sounds like an execution order issue. What could be happening is that OnAction within TestClass is being called before the delegate hookup. Try the following:
public class TestClass : ParentClass
{
public event EventHandler<string> MyDelegate;
public class TestClass(Action<string> myAction)
{
MyDelegate += myAction;
}
public override void OnAction(Context context, Intent intent)
{
var handler = MyDelegate;
if (handler != null)
{
handler(this, "test");
}
}
}
Just pass the delegate through the constructor, this should make sure its hooked up before any calls to OnAction()
You can pass through the handler in a couple ways:
1.) As an anonymous method:
private TestClass mytest= new TestClass ((sender, info) => { Console.WriteLine("Event Attached!") });
2.) Pass in the method group:
public class MyEventHandler(object sender, string e)
{
Console.WriteLine("Event Attached!");
}
private TestClass mytest= new TestClass(MyEventHandler);
I generally recommend the second way as it allows you to unhook the handler and do clean up once you are done with it:
myTest.MyDelegate -= MyEventHandler;
My interface has an event that don't has an arguments
public interface IMyInterface
{
event EventHandler OnSomethingHappened;
}
Here is how I am implementing it.
public class MyBaseClass : IMyInterface
{
private event EventHandler onSomethingHappened;
public event EventHandler OnSomethingHappened
{
add
{
onSomethingHappened-= value;
onSomethingHappened+= value;
}
remove
{
onSomethingHappened-= value;
}
}
}
But somehwere else when I try to use it as follows
if ( MyBaseClassInstance.OnSomethingHappened != null )
MyBaseClassInstance.OnSomethingHappened();
I get following compilation error
The event 'ConsoleApplication1.IMyInterface.OnSomethingHappened' can
only appear on the left hand side of += or -=
What am I doing wrong?
This is how your code might look:
public interface IMyInterface
{
event EventHandler OnSomethingHappened;
}
//implement the interface
public class MyBaseClass : IMyInterface
{
public event EventHandler OnSomethingHappened;
public void DoSomeLogicWhichRaisesTheEvent()
{
if (OnSomethingHappened != null)
{
MyBaseClass sender = this;
var eventArgs = new EventArgs();
//let all subscibers to event know that the event happened
OnSomethingHappened(sender, eventArgs);
}
}
}
public class ConsumerClass
{
private IMyInterface myBaseClassInstance;
public ConsumerClass()
{
myBaseClassInstance = new MyBaseClass();
//attach to the event
myBaseClassInstance.OnSomethingHappened += MyBaseClassInstance_OnSomethingHappened;
}
private void MyBaseClassInstance_OnSomethingHappened(object sender, EventArgs e)
{
//react to the raised event
throw new NotImplementedException();
}
}
As you can see you need to implement the IMyInterface interface, and when MyBaseClass needs to raise the event you call OnSomethingHappened(sender, eventArgs);
ConsumerClass is where you need to consume, or to do something, as a reaction to the raised event.
You may consider to rename MyBaseClass to some other name, without 'Base' in it, because it is not an abstract class.
I am working a problem which is about delegate and event. I am a newbid in this aspect. I don't know how to call the event.
Would some tell me?
Thanks in advance.
Here is simple example to call event....
// event_keyword.cs
using System;
public delegate void MyDelegate(); // delegate declaration
public interface I
{
event MyDelegate MyEvent;
void FireAway();
}
public class MyClass: I
{
public event MyDelegate MyEvent;
public void FireAway()
{
if (MyEvent != null)
MyEvent();
}
}
public class MainClass
{
static private void f()
{
Console.WriteLine("This is called when the event fires.");
}
static public void Main ()
{
I i = new MyClass();
i.MyEvent += new MyDelegate(f);
i.FireAway();
}
}
There is Link which may helpful.
The event can be invoked in the class in which it is declared. First you'll usually want to check if your event is null.
if (MyEvent != null) MyEvent(this, new EventArgs());
The arguments you pass to the event will depend on the declaration of the event. To give you a little more background, an event is just a compiler trick. When an event such as
public event ChangedEventHandler Changed;
is compiled it will look like
protected ChangedEventHandler _change;
public ChangedEventHandler Change
{
add { _change += value; }
remove { _change -= value; }
}
so anything inside where it is declared will use _change, while anything outside will use Change. In other words, inside where it is declared, it is just a delegate, and all the normal rules apply.
To resuse the event you just need to attach event with the you control for example .
buttonone.Click+= event1;
buttonTwo.Click+= event1;
Fore more details have look : C# Event Implementation Fundamentals, Best Practices and Conventions
Once you have defined the delegate, you need to define when to call the event. I mean you can call the event at assignment of any value to the specific variable.
here is the example of defining the delegate with the same variable class.
public class callbackdel : EventArgs
{
public readonly string resp = null;
public callbackdel(string s)
{
resp = s;
}
}
public delegate void WorkerEndHandler(object o, callbackdel e);
Now in the control you are using, you need to add this method.
public void OnWorkEnd(object o, callbackdel e)
{
WorkEnd(o, e);
}
after creating method and defining the delegate, you can fire the event from any of the delegate simply by calling the method.
OnWorkEnd((object)this, e);
When using an Event you first have to declare it:
// Create some custom arguments for the event
public class SampleEventArgs
{
public SampleEventArgs(string s)
{
Text = s;
}
public String Text {get; private set;}
}
// Define a class that uses the event
public class EventPublisher
{
// Declare the delegate
public delegate void SampleEventHandler(object sender, SampleEventArgs e);
// Declare the event.
public event SampleEventHandler SampleEvent;
// Wrap the event in a protected virtual method
// to enable derived classes to raise the event.
protected virtual void RaiseSampleEvent()
{
// Raise the event by using the () operator.
if (SampleEvent != null)
SampleEvent(this, new SampleEventArgs("Hello"));
}
}
You can then subscribe to the event:
EventPublisher publisher = new EventPublisher();
publisher.SampleEvent += new EventPublisher.SampleEventHandler(SampleEventHandler);
public void SampleEventHandler(object sender, SampleEventArgs args)
{
}
Your event handler will be called when EventPublisher executes RaiseSampleEvent()