iBent
iBent

Reputation: 402

Wait for mouseclick in function

In one of my classes I got List<Point> mousePointList = clickArea.getClicks();

The function getClicks() should return a list of points that contains an entry for every click made after executing the function. After clicking multiple times you should be able to finish the function with an ENTER click.

My problem is that I can't get the function to wait for the MouseClick function.

Upvotes: 0

Views: 2672

Answers (2)

Luaan
Luaan

Reputation: 63742

You don't want to wait for MouseClick. What you want to do is wire up a continuation from inside of your function:

void Main()
{
    Form frm = new Form();
    var btn = new Button { Text = "Start" };
    btn.Click += (_, __) =>
        {
            var clicks = new List<Point>();

            MouseEventHandler mouseUp = (s, e) =>
                {
                    clicks.Add(e.Location);
                };

            var eventHelper = new EventHelper { MouseUp = mouseUp };

            KeyEventHandler keyUp = (s, e) =>
                {
                    if (e.KeyCode == Keys.Return)
                    {
                        frm.MouseUp -= eventHelper.MouseUp;
                        frm.KeyUp -= eventHelper.KeyUp;
                        btn.Enabled = true;

                        // Finish
                        clicks.Dump();
                    }
                };

            eventHelper.KeyUp = keyUp;

            frm.MouseUp += mouseUp;
            frm.KeyUp += keyUp;
            btn.Enabled = false;
        };

    frm.Controls.Add(btn);

    Application.Run(frm);
}

class EventHelper
{
    public MouseEventHandler MouseUp;
    public KeyEventHandler KeyUp;
}

Note that the clicks variable stays local - there's no need to explicitly define a field on the whole form or anything like that. Registering and unregistering the event handlers is a bit clunky, but I hope this shows the intent clearly enough. Do not forget that the event handlers are global, though - if there's more buttons that can be possibly waiting for those events as well, they'll all be receiving at the same time. This may or may not be a problem, depending on your exact scenario (but it's inherent to simply having a single form - there isn't really a way around this other than disabling all the conflicting buttons when one of them is pressed).

It's also quite easy to utilize await to avoid having to write the callback manually - I'll leave that as an excercise for the reader :) This is very handy for reliability - the sample code can easily lead to the button being disabled forever, as well as leaving the event handlers assigned forever if there's an exception somewhere. With await, you'd just use try-finally to handle removing the event handlers and enabling the button again.

Upvotes: 1

Patrick Hofman
Patrick Hofman

Reputation: 156978

I think you got your logic wrong. You can't wait for a mouse click, instead you will just receive an event (through your Forms MouseClick event or so) and you will act accordingly.

You can do the same for the ENTER: if someone hits ENTER and you don't allow it yet, don't handle the event any further. You can use the KeyDown event for that.

Upvotes: 1

Related Questions