0

So, I have an ASPX file with 9 buttons (Working on a TicTacToe game so each button has the same OnClick method) and on C#, I find and store all these buttons in an array like so:

public partial class Index : System.Web.UI.Page {
    protected static Button[] buttons;

    protected void Page_Load(object sender, EventArgs e) {
        if (!IsPostBack) {
            initialConditions();
        }
    }

    private void initialConditions() {
        buttons = findButtons();

        // Can access and modify buttons here
        foreach (var btn in buttons) {
            btn.Text = "this does work";
        }

        // Cant modify buttons here
        accessButtons();
    }

    private Button[] findButtons() {
        List<Button> tmpButtons = new List<Button>();
        foreach (var item in board.Controls) {
            if (item is Button) {
                tmpButtons.Add((Button)item);
            }
        }
        return tmpButtons.ToArray();
    }

    private void accessButtons() {
        foreach (var button in buttons) {
            button.Text = "this wont work";
        }
    }
}

I can modify buttons after initialising the array in initialCondition() method but accessButtons() method cannot access those very same buttons. I guess it has something to do with reference and instance stuff but I cannot get my head around this. How can I access and modify this array of buttons anywhere within the class easily with for loops and such?

Edit: I tried initialising the array like protected static Button[] buttons = findButtons(); but when I do so, I have to make accessbuttons() a static method but then it cannot access board element on ASPX so I could not figure that one out.

5
  • The code you've produced does not give any compile errors. What do you mean by "accessButtons() method cannot access those very same buttons"? Commented Apr 27, 2020 at 20:13
  • Is it intentional that buttons is static? Do you want multiple instances of the class to manipulate the same collection? Commented Apr 27, 2020 at 20:14
  • Don't make the array static! If you do, it's shared between every instance of the page for that process. Commented Apr 27, 2020 at 20:19
  • @RufusL Yes, it does not produce any compilation errors but it simply does not work. accessButtons should be changing every buttons text to "this wont work" but it does not. And no, buttons should not have been static. It seems I forgot to revert it back after one of my trials Commented Apr 27, 2020 at 20:24
  • Removing static may be enough to resolve the issue, then. Commented Apr 27, 2020 at 20:27

2 Answers 2

2

Change this:

protected static Button[] buttons;

To this:

protected List<Button> buttons;

And this:

private Button[] findButtons() {
    List<Button> tmpButtons = new List<Button>();
    foreach (var item in board.Controls) {
        if (item is Button) {
            tmpButtons.Add((Button)item);
        }
    }
    return tmpButtons.ToArray();
}

To this:

private List<Button> findButtons() {
    return board.Controls.OfType<Button>().ToList();
}

And finally this:

protected void Page_Load(object sender, EventArgs e) {
    if (!IsPostBack) {
        initialConditions();
    }
}

To this:

protected void Page_PreInit(object sender, EventArgs e) {
    initialConditions();
}

Notice that every one of these changes results in less code than you had before.

For this last change, remember that every server event (including button clicks) is a complete round-trip between the web server and the browser, with a completely different instance of the page class. You have to rebuild that array on every run through the page life cycle, and if you want ViewState to work you need to do it before Page_Load().

Sign up to request clarification or add additional context in comments.

5 Comments

It is a lot cleaner than my code and I did not know Page_PreInit so thank you :) I know have another tool in my arsenal. However, these do not solve the problem of accessing buttons from another method themselves. The solution was to use foreach (var button in findButtons()) instead of foreach(var button in buttons) so it can access the very same buttons instead of their references.
@ÖzençB. These changes should let you use the buttons member in any other method (this is another reason we removed the if(!IsPostBack) check). Calling findButtons() every time does the extra work of searching and building the collection every time.
I applied your recommendations but accessButtons() still cannot access buttons. I get an System.NullReferenceException: 'Object reference not set to an instance of an object.' error.
accessbutton() can't run until after initialConditions()
Oh, and initialConditions() needs to keep the buttons = findButtons(); code. You have to do this exactly once at the beginning of the page life cycle.
0

What if you change this:

   private void accessButtons() {
        foreach (var button in buttons) {
            button.Text = "this wont work";
        }
    }

To this:

   private void accessButtons() {
        foreach (var button in findButtons()) {
            button.Text = "this wont work";
        }
    }

Because this;

protected static Button[] buttons;

is protected static

So you can only access it like so;

var buttons = Index.buttons;

but it will be null or empty since its not filled anywhere.

3 Comments

This is not an issue of access. protected means that only memebers of the class or other classes that inherit this class can access the field. static means that there's only one instance of the object that's accessible to all instances of the class. Both findButtons and accessButtons have the same access level, therefore the code to iterate the buttons will work the same in both of them.
Wow, this solution is genius. I think I now see what it is doing and what I was doing wrong. It does access those buttons directly instead of their references, right?
Adding the Index prefix from inside the class is optional (and flagged as "redundant" by resharper). Also, this code is modifying a temporary list of buttons returned from the findButtons() method, not the static Button[] buttons field.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.