I got an event from special API I'm working with, the event I'm working with is defined as
public event EventHandler<QuoteEventArgs> OnQuote
public class QuoteEventArgs : EventArgs
so what I'm trying to do is attach a method to run when I got a new Quote listening to this event.
so what I do is:
myInstance.OnQuote += new EventHandler<QuoteEventArgs>(doThis);
And the method is defined as:
public void doThis(object sender, QuoteEventArgs e){
//code here..
}
The error I get is:
Cannot implicity convert type 'System.EventHandler<MT4API.QuoteEventArgs>' to 'System.EventHandler'
but I don't seem to have a special eventHandler on the API either, so not quite sure how to make that work.
From the comment discussion, it appears that you are using a version of the library in which the event does not have a generic type, i.e. the signature is
public event EventHandler OnQuote;
This means you will also have to consume it in a non-generic way:-
myInstance.OnQuote += new EventHandler(doThis);
public void doThis(object sender, EventArgs e){
var myArgs = (QuoteEventArgs)e;
...
}
My guess is that there are two classes with the name QuoteEventArgs, perhaps one from a referenced DLL and one from a generated proxy. Ensure that if you've got usings that the usings are correct.
Related
I am developing a MEF application. I am using a plugin as a publisher and another as a subscriber. For the current issue I guarantee that both plugin instances are active. On the subscriber I subscribe to the event and on the publisher I iterate over the invocation list and call the BeginInvoke to raise the event asynchronously as so:
Publisher:
public class BackchannelEventArgs : EventArgs {
public string Intensity { get; }
public BackchannelEventArgs(string intensity) {
this.Intensity = intensity;
}
}
public class Publisher {
public event EventHandler<BackchannelEventArgs> BackchannelEvent = delegate { };
private void BackchannelEventAux(string bcintensity) {
Plugin.LogDebug("BACKCHANNEL EVENT, sending to " + BackchannelEvent.GetInvocationList().Length + " subscribers: " + bcintensity);
var args = new BackchannelEventArgs(bcintensity);
foreach (EventHandler<BackchannelEventArgs> receiver in BackchannelEvent.GetInvocationList()) {
receiver.BeginInvoke(this, args, null, null);
}
}
}
Subscriber (relevant snippet, the Init is being called by a pluginsManager in which I can see the logs):
class Subscriber {
public void Init(){
LogInfo("Before subscribing");
publisher.BackchannelEvent += HandleBackchannelEvent;
LogInfo("After subscribing");
}
private void HandleBackchannelEvent(object sender, BackchannelEventArgs e) {
LogDebug("Handle Backchannel!");
}
}
Now, the Log you see on the event handler is not called at all. I have 4 other events that follow the same structure and somewhat this event in particular is not being called (I can see the logs on the other events). The other plugins follow the exact same structure.
Already tried:
Call synchronously BackchannelEvent(this, args) but the results are the same;
Subscribe this same event on the other plugins as well but the issue remains on this single event (and not on the others who follow the same structure).
I hope you can give me some help on this.
Thank you
Edit: The shown code is a snippet. The Init method is being called by the pluginsManager. I have put a log before the subscribing call and I can confirm that I am indeed subscribing.
Edit2: The number of elements in the InvocationList is in fact 2 (the empty delegate and the subscriber) so it checks out.
Okay. I don't know why but I figured out the solution so that other ones who stumble with the issue can find a solution. It was related with a extension I created for the Random class (which wasn't throwing a exception although... so it might be a bug on C#, I can't really explain). The Random extension is provided by an external NuGet package I created.
Version A (without using the Random Extension):
Body of the EventHandler:
LogDebug("Inside Handler");
double intensityValue2 = GetRandomNumber(Settings.MinimumIntensity, Settings.MaximumIntensity);
double frequency2 = GetRandomNumber(Settings.MinimumFrequency, Settings.MaximumFrequency);
int repetitions2 = GetRandomInt(Settings.MinimuMRepetitions, Settings.MaximumRepetitions);
Version B (using Random extension):
Body of EventHandler:
LogDebug("Inside Handler");
double intensityValue2 = random.GetRandomNumber(Settings.MinimumIntensity, Settings.MaximumIntensity);
double frequency2 = random.GetRandomNumber(Settings.MinimumFrequency, Settings.MaximumFrequency);
int repetitions2 = random.GetRandomNumber(Settings.MinimuMRepetitions, Settings.MaximumRepetitions);
Version A is the one that it is working. The Logs are guaranteed to appear. I don't know why it isn't letting me use extensions but it is solved for now. It would make sense if the Random extension threw an exception but it is not the case...
If any other person stumbles upon the issue I hope this helps you figure out the issue faster than me.
Thank you
Edit: typo
This may have been asked several times, but I don't know what to search for..
Anyway. I have a class called Character. Inside of it I want to have a collision component that I have called RectangleCollision. Inside of it there is a function called IsOverlapping that checks for overlap.
I want to have a function that can be modified for each game object. For example create a function called OnBeginOverlap(); that will fire everytime the collision component detects a collision.
Is there any way that I can bind this function as delegate or event? Or something?
You have to read about events and delegates. There are plenty of examples on the web. The easiest I managed to find when I was trying to understand the subject was this:
The Simplest C# Events Example Imaginable
You can also check out the below (you can compile this as console application):
class Character
{
public delegate void OverlappingHandler(Character character, EventArgs e);
public event OverlappingHandler OverlappingEvent;
public void IsOverlapping()
{
bool overlapping = true;
if (overlapping)
{
if (OverlappingEvent != null)
{
OverlappingEvent(this, null);
}
}
}
}
class Program
{
static void Main(string[] args)
{
Character c = new Character();
c.OverlappingEvent += OverlappingEventHandler;
c.OverlappingEvent += OverlappingSecondEventHandler;
c.IsOverlapping();
Console.Read();
}
static void OverlappingEventHandler(Character character, EventArgs e)
{
Console.WriteLine("We have overlapping here!!");
}
static void OverlappingSecondEventHandler(Character character, EventArgs e)
{
Console.WriteLine("Seriously, we have overlapping !!");
}
}
So step by step:
Create a delegate, which is a bridge between your event and the code you want to run when event is triggered. You give parameters to a delegate, which are (object sender, EventArgs e) - in this example sender is the Character class, arguments are used to send additional info - for example type of character.
Create event of our delegate type
In our function IsOverlapping() there would be your logic checking if there is overlapping happening. If there is, you fire up event. You should check first if there is anything connected to the event (hence the if (OverlappingEvent != null)) - if some there is something, fire up the event.
In the Main() you create an instance of the class and...
Subscribe your event handlers to it, so the code that should be executed when the event is triggered. I connected two methods, just to show that you can subscribe more than one.
Now when you run c.IsOverlapping() this is what happens:
your logic to check overlapping runs,
if there is overlapping, there will be a check if OverlappingEvent has code subscribed (it does in Main()),
if it does event will be triggered,
code subscribed to the event runs - in this case your code in Main().
You can compile this as console app and it will display 2 lines:
We have overlapping here!!
Seriously, we have overlapping !!
Hope this helps.
This question already has answers here:
How do I programmatically wire up ToolStripButton events in C#?
(2 answers)
Closed 7 years ago.
Me again, and it's another problem with my plugin parser for my c# browser, I'm trying to add a eventhandler to make it to where when you hit the plugin button it does something. The reason i am having to do this in code is because it is loading the plugins from files, and they are not hard-coded.
Here's my code, It will look pretty familar to the last one if you saw it
toolStrip1.Items.Add( pluginButton );
pluginButton.Image = Simple_Browse.Properties.Resources.plugin;
pluginButton.Alignment = ToolStripItemAlignment.Right;
pluginButton.ToolTipText = TitlePlugin;
pluginButton.Click += StartPlugin();
private EventHandler StartPlugin()
{
PluginPage plgp = new PluginPage();
plgp.Show();
plgp.Text = PlgTitle2;
}
So the code is pretty basic, but im getting an error at private EventHandler StartPlugin() The error is not all code paths return a value Please help!
You probably meant to do this instead:
pluginButton.Click += StartPlugin; // not StartPlugin()
private void StartPlugin(object sender, EventArgs e)
{
PluginPage plgp = new PluginPage();
plgp.Show();
plgp.Text = PlgTitle2;
}
It looks like you may need to read a bit more on how delegates and event handlers work.
You're requesting an EventHandler which means you have to return an EventHandler. In your handler there is no return, so this error is thrown.
You could use private void StartPlugin(). void doesn't request anything to return.
So your code will look like this:
pluginButton.Click += StartPlugin;
private void StartPlugin(object sender, EventArgs e)
{
PluginPage plgp = new PluginPage();
plgp.Show();
plgp.Text = PlgTitle2;
}
private EventHandler StartPlugin()
This line, specifically "EventHandler", means you're returning an EventHandler. Your code does not do this. To link the EventHandler with the button click, you dont just use a line, you also need a return, (e.x return button1.Click;) because if i used return null; it would just do the action once you binded it.
Sorry I have a bit specified question. Yes this is related to setting a custom Event Handler to an event. Yes, this type of questions may have already been asked many times, but here I have to restrict to WinSCP situation.
Refer to example in Session.SynchronizeDirectories method:
http://winscp.net/eng/docs/library_session_synchronizedirectories
I am converting the C# example to C++/CLI, but encounter a problem.
In C#, it is a no-brainer to set as:
Session session = new Session();
session.FileTransferred += FileTransferred;
...
private static void FileTransferred(object sender, TransferEventArgs e)
{
....
}
In C++/CLI, I do the following:
WinSCP::Session ^ session = gcnew WinSCP::Session();
session->FileTransferred += gcnew EventHandler(FileTransferred);
...
static void FileTransferred(System::Object ^sender, WinSCP::TransferEventsArgs ^e)
{
....
}
But I get this error:
function FileTransferred() does not match the delegate type 'void (System::Object ^, System::EventArgs ^)'.
I try changing to FileTransferred(System::Object ^sender, EventArgs ^e), but then the whole body of FileTransferred() become invalid.
session->FileTransferred += gcnew EventHandler(FileTransferred);
EventHandler is the wrong delegate type. You need to create a WinSCP FileTransferredEventHandler delegate instead. Fix:
session->FileTransferred += gcnew WinSCP::FileTransferredEventHandler(FileTransferred);
Beware that you also mis-spelled WinSCP::TransferEventsArgs, one s too many.
I actually was just a step away from the answer.
In C#, after typing the += after session.FileTransferred, I was prompted to hit Tab button. I then saw the following:
session.FileTransferred += new FileTransferredEventHandler(FileTransferred);
This FileTransferredEventHandler() could pick up the correct function signature FileTransferred(object sender, TransferEventArgs e) (instead of requiring FileTransferred(object sender, EventArgs e).
I go back to C++/CLI and do the same:
session->FileTransferred += gcnew FileTransferredEventHandler(FileTransferred);
Compile. And no complain.
I am new to jabber and xmpp. I am developing Chat client application using c#, wpf and jabber-net. I have created Register Form but i got some error in Code behind.
jc.OnRegisterInfo += new RegisterInfoHandler(this.jc_OnRegisterInfo);
jc.OnRegistered += new IQHandler(jc_OnRegistered);
No overload for 'jc_OnRegistered' matches delegate 'jabber.client.IQHandler'
No overload for 'jc_OnRegisterInfo' matches delegate 'jabber.client.RegisterInfoHandler'
Thanks in advances...
The OnRegisterInfo event is a RegisterInfoHandler which is declared as:
public delegate bool RegisterInfoHandler(Object sender, Register register);
You must have a method that returns bool, and takes an object as a first parameter, and a Register as a second parameter.
The OnRegistered event is an IQHandler which is declared as:
public delegate void IQHandler(Object sender, IQ iq);
You must have a method that returns void, and takes an object as a first parameter, and an IQ as a second parameter.
Make sure that jc_OnRegisterInfo looks like this:
private bool jc_OnRegisterInfo(object sender, Register register)
{
// ...
}
and jc_OnRegistered looks like this:
private void jc_OnRegistered(object sender, IQ iq)
{
// ...
}