views:

181

answers:

4

Hello, I am trying to write a method that loops and repeatedly calls other methods. There is a single place inside the loop that I need to pause and wait for a user to click one of several buttons on the GUI. I have done this with command line code before, but I'm not sure how to wait and check it any buttons have been clicked. If someone could help me out, I would be very grateful. Below is an example of what I would like to do.

While(MoreLeftToD0){
Method1();
WaitForUserToClickButton();
If(Button1 was clicked)
    ProcessWithButton1();
else
    ProcessWithButton2(); }

EDIT: I think a bit more info may help, and perhaps I am thinking about this incorrectly. I am trying to build a simple game that has 2 players 0, 1, or 2 of these players may be bots and the other(s) will be humans. I want a basic Player class that has Human and Bot classes which inherit from Player.

The loop is for the game board and I want to just be able to call CurrentPlayer.GetMove(gameBoard) which, for the bot, will pass the game board in and let them decide on a move. However, if it is a human, GetMove() should wait for the user to click the button on the GUI stating what they want to do on the board and then process the click accordingly.

Hopefully this will clear up the purpose a bit. If there is a better way to do this, I'd love to hear suggestions. Thanks!

A: 

No need to do all this.

All you need is to use event handler in the Windows Form.

Here's a walkthrough that you can read.

For example, in C#, you can subscribe to the event, and write whatever logic you have in mind in the following code:

private void button1_Click(object sender, System.EventArgs e) 
{
// Add event-handler code here.
}
Ngu Soon Hui
A: 

So, in WinForms you already have a message loop. The way you deal with this is by subscribing to button click events. This article below may help clear some things up for you:

http://articles.techrepublic.com.com/5100-10878%5F11-1050284.html

If this is not what you meant please update and I will try to edit accordingly.

BobbyShaftoe
+3  A: 

Typically, you would do this by splitting up the work to be done before, and the work to be done after, the button click.

Part1()
{
  DoSomething();
  btn.Enabled = true;
}

private void button1_Click(object sender, EventArgs e)
{
  btn1.Enabled = false;
  Part2();
}

Do something, enable the button, which you've hooked to the button1_Click event handler, and when the user clicks the button, disable it so he can't click it again.

Michael Petrotta
This would be fine, but in my app I don't always want to wait for a button click. If the current Player is a human, I need to wait for a click. However, if they are a bot there is no button click to wait for. I just need them to process the board, make and make their move.
Bobby
Not sure I understand. Can you detect if it's a bot? If so, just call Part2() directly in that case.
Michael Petrotta
if (IsBot) { Part2() } else { btn.Enabled = true }
Michael Petrotta
I could do that, I was just hoping to treat the bot and the human exactly the same. Regardless, just load the current Player (could be a bot or a human) and call .GetMove().If I can't, I can't. I appreciate your help though.
Bobby
Hmmm. Well, you could clean it up a bit, but given the way the Windows message pump works, I think you're stuck with some variant of this. If your logic is happening on the main UI thread, you can't just stop and wait (at least, not without ugly hacks). If you stop, and don't return control to the message pump, your UI will stop updating and look like it crashed.
Michael Petrotta
A worker thread, doing the actual work, then asking the UI to prompt the player (if he's human), and spinning on the response - that might work. Lots of headaches that way, though.
Michael Petrotta
Alright, that was what I thought originally, but I was hoping there was a way to handle this I didn't know about. I will use your method and run different code for a bot vs. a human when I need input from the gui. Thanks again for all your assistance.
Bobby
A: 

From what you describe in the comments on michael's post, you might be better off inheriting from an IPlayer interface, or if Part1 and Part2 are identical, a base class.

public class Player
{
    protected void Part1() { /* ... */ };
    protected void Part2() { /* ... */ };
}

public class HumanPlayer : Player
{
    public void GetMove()
    {
        Part1();
        GetMouseClick();
        Part2();
    }
}

public class BotPlayer : Player
{
    public void GetMove()
    {
        Part1();
        Part2();
    }
}

That way you've just got Player objects which, you still can treat the same.

List<Player> players = new List<Player>()
    {
        new BotPlayer(), 
        new HumanPlayer()
    };

// ...

foreach (Player p in this.players)
    p.GetMove();
SnOrfus