Hi.

I'm currently messing around with C# and decided to write a small game. One of the first things I am doing is setting up the game's GUI, which I am designing myself with help from XNA (but not Windows Forms).

I've already made proof-of-concept buttons that can be placed, scaled, given multiple images (default, clicked, hovered, and disabled), as well as a "GUI" element that can hold sets of buttons and handle their enabled/disabled state en-masse (for switching between menus).

My problem is with the function of the buttons themselves. Right now, when the mouse is clicked, it runs through the current GUI's buttons using a function of my Button class called "clickCheck" to see if the mouse has been clicked within a specific button. This works great when I have only a few buttons, but it seems like it will get out of control if I ever get a "game" going as there will be many buttons.

The reason is that in the "foreach" statement, where I run all the clickChecks, I have to put in if statements for every button, for every GUI. So right now it is something like:

if(aButton.clickCheck == true) {
          ...whatever it does...
      }
      if(bButton.clickCheck == true) {
          ...whatever it does...
      }
      if(cButton.clickCheck == true) {
      .
      .
      .
}

So my question is this: is there a way to define a function that each individual button will perform when clicked. This way I could, say, set up each GUI in its own source file. In that source file I would create each button (and its function when clicked) individually and put them into the GUI's button list. Then, when running the foreach clickCheck I can just use something like:

foreach(Button aButton in gui.buttonList) {
    if(aButton.clickCheck == true) {
          [B]aButton.function()[/B];
    }
}

Where each individual button has its own function when clicked. In other words the bolded part is what I'm looking for. Is there a way to set this up? I mean other than creating an inherited class for every button...

What I've understood from your question you need to know which button clicked (and it's not work Probably with huge number of buttons) I've better scenario is to Create ONE event handler for Button Click and assign this handler to all buttons.
I've 10 buttons with text say (1....10)

private void button1_Click(object sender, EventArgs e)
{
Button ClickedButton = (Button)sender;

switch(ClickedButton.Text)
{
case "1":
...
break;
case "2":
...
break;
..
..
..
..
}           
}

I hope I've understood you well.

Unfortunately that's not my problem. I know which button is clicked (using my "clickCheck" function), but in order to assign a function to a button I have to take every single button and put it into an if statement (or switch-case statement like you used). If I had 30-50 buttons spread out across four different GUIs (like, say, inventory, player profile, main menu, combat, etc) I would have a very large section of code that would be a bit out of place.

So I would instead like to know if there is a way to "assign" a function to a button so that I could later just call that function without using a click check. Here's an example of how it is now:

if(aMouse.LeftButton == ButtonState.Pressed) {
   // check if FirstButton has been clicked
   if(FirstButton.clickCheck(aMouse.X, aMouse.Y) == true) {
      this.Quit();  // in this case, FirstButton's function is to quit
   }
   // check if SecondButton has been clicked
   if(SecondButton.clickCheck(aMouse.X, aMouse.Y) == true) {
      // something else
   }
   // check if ThirdButton has been clicked...
   if(ThirdButton.clickCheck(...) == true) {
   .
   .
   .
   // and so on for all buttons, of which there could be too many
}

The problem with this (or a switch-case) statement is that I have to define my buttons from within the mouse's event check. If I have a lot of buttons that's a very very long set of if statements and isn't a very elegant way of doing things.

Instead I would like something like this:

if(aMouse.LeftButton == ButtonState.Pressed) {
   // run one loop through a list of buttons
   foreach(Button aButton in guiList[currentGUI].buttonList) {
     // if a button returns a "true" for clickCheck ( i.e. it's been clicked)
     if(aButton.clickCheck == true && aButton.Enabled == true) {
        // run that Button's function
        aButton.Function();
     }
   }
}

Let's say that FirstButton is the button that returns a "true" result of clickCheck() (i.e. it's been clicked). Somewhere earlier in the code, when I created that button, I could have made the button in such a way that when "aButton.Function()" was called it ran "this.Quit()".

So I was able to create the button somewhere else and assign a function to it for use later if its Function() method was called.

The best part about this method is that the main game code can be relatively clean as all the buttons (and their functions) can be created and assigned in another source file.

Basically you need to made a collection of controls as the way the winform work.

So say we have:
WinControl
{
Event handle Click
}
Button : WinControl
{
}
ControlCollection
{
ArrayList ChildrenControl;
}
Form : WinControl
{
}

Everytime you create a new button, add it into the Form control.
So when you click, you run through the list:
for(i = 0 -> form.childrenControl.length)
childrenControl.click()

I guess you haven't got good experience with Polymorphism (which is really important for game programming).

Moreover, you could assign a custom handler for a button, so the button could work the same way as the button in winform work.

What game are u trying to make anyways? I made quite a few games in XNA and good to know people with the same interest :).

Well, what he saying is he want to make his own control in XNA platform which is not relate to WinForm. The title is confusing I guess. It's not a custom control. Moreover, it should be in game dev instead of in C#.

Look Wallish, my scenario works fine if you also create buttons at runtime!!
suppose I've my button OnClick event handler

void AnyButtonOnClick(object sender, EventArgs e)
{
Button ClickedButton = (Button)sender;
switch(ClickedButton.Text)
{
case "Quit":
Quit();
break;
}           
}

This creates button at runtime

Button btnQuit = new Button();
...
...
...
btnQuit.Click+=new EventHandler(AnyButtonOnClick);

I don't see any problem with my scenario except you should have pre-defined methods.

If you don't understand me, ask which part you don't.

This article has been dead for over six months. Start a new discussion instead.