Search code examples
c#eventsxnaclickmonogame

How to add a "Click Event" to a class? in C#


So this is how far I got. (not that much I know) but I have something like this: A class called "SplashScreen"

private DynamicButton dynButton;

public override void Init(ContentManager Content)
    {
        base.Init(Content);

        dynButton = new DynamicButton("Test", new Vector2(450, 100), Color.White);} 

private void Dyn_Click(object sender, EventArgs e)
    {
        dynButton.ObjColor = Color.DarkOrange; //I want to do stuff here
    }

public override void Update(GameTime gameTime)
    {
        base.Update(gameTime);
        dynButton.Update(gameTime);
        dynButton.Click += Dyn_Click;
    }

And in my Dynamic Button class as follows:

   public event EventHandler Click;

   public override void Update(GameTime gameTime)
    {
        base.Update(gameTime);
        this.Click += DynamicButton_Click;
    }

    private void DynamicButton_Click(object sender, EventArgs e)
    {

    }

I don't really know how to get the Click event right. So like I have to check my bounds from the object with my mouse that's what I know but how can I make it that the events fires. I just want to call like dynButton.Click += myMethod and in this method I would do stuff. Hope you understand what I mean.(I'm pretty new)


Solution

  • Xna and Monogame call the Update method between 30 and 60 times per second on a normal situation (based on the device).

    This means that, if you want to use events; it's a really bad idea to subscribe to them on the method itself as you will get a new subscription every time. In the code you posted, you subscribe to the event 60 times per second!

    public event EventHandler Click;
    
    public override void Update(GameTime gameTime)
    {
        base.Update(gameTime);
        this.Click += DynamicButton_Click; // Called 60 times per frame on a PC!
    }
    

    I'm not saying you shouldn't subscribe on such a method, you could but based on a condition. Never do it freely.

    That being said, what you want is to subscribe to the event in a safe place and then fire it when a condition is met. The subscription, in you scenario, would take place on the Splash screen:

    public override void Init(ContentManager Content)
    {
        base.Init(Content);
    
        dynButton = new DynamicButton("Test", new Vector2(450, 100), Color.White);
        dynButton.Click += SomeoneClicked;
    } 
    
    private void SomeoneClicked(object sender, EventArgs e)
    {
        // Your code here.
    }
    

    The dynamic button is the one responsible for firing the event (but not responding to the event itself).

    public event EventHandler Click;
    
    public override void Update(GameTime gameTime)
    {
        base.Update(gameTime);
        if(this.Click != null)
            Click(null, null);
    }
    

    You can find more info about EventHandlers on the MSDN. As a final note, and I think this is the biggest problem you are facing; you need to know exactly when to fire the event. based on your comments, you need to check for a particular condition based on the position of the mouse, which is easily done via the MouseState provided methods:

    MouseState ms = Mouse.GetState();
    var positionX = ms.X;
    var positionY = ms.Y;