I've just started c# having done VB and a bit of c++. I think c# is probably a more viable option than ++, thus here I am.


I've had this problem in a few languages. How do you create an array in code that is linked to an array of text boxes? It's difficult to explain... I want the user to be able to enter certain numbers in a 9 x 9 array - which will be 81 textboxes (or so I plan, any suggestions for alternatives are welcomed), some of the array will not require data entered into it. Then I want those numbers to be taken into a 9 x 9 array within code. But the problem is that you cannot create a loop to do this. Because you must name textboxes like "txt00, txt01, etc", you can't refer to them in a loop within the code.

So what is the best way to get the user to enter numbers into this array whilst still maintaining a reasonable looking interface.

Recommended Answers

All 26 Replies

Ah, but you can! Using the Controls.Find() method, you can search for an instance of a control on a form. So, if you name your text boxes "txt001", "txt002", etc., you can run code like this:

Controls[] x = this.Controls.Find(sControlName, true);

to get an array of controls that match the string in "sControlName". Assuming only one control matches your string, code like this:

TextBox z = (TextBox)x[0];

will give you a variable, "z", that can be handled like any TextBox.

I think a better approach might be to explain what you're trying to accomplish. You cannot tell me that any user will entertain the thought of running an application with 80+ text boxes on a form.

Mike's advice for iterating the controls by name will solve your problem if you do decide to use the 80+ textbox approach. Also -- You can name your text boxes where they can be easily referenced in code: "txt_8_2" for element[8][2]. I haven't actually tried to use an underscore in a control name but if it isn't allowed "txt82" serves the same purpose since the array is a fixed single digit integer.

sorry about the slow response...

the purpose of the program is actually to solve Sudoku puzzles. So, I need the user to enter numbers which are present from the existing puzzle. Hence i need many textboxes. Many of which will be empty initially.

Thanks Mike as well, I will see what I can do with that.

I can't seem to get it to work.

"Error	1	'System.Windows.Forms.Control.Controls' is a 'property' but is used like a 'type'	C:\Users\Dan\AppData\Local\Temporary Projects\Sudoku Solver\Form1.cs	21	13	Sudoku Solver
"

" Error	2	The name 'scontrolname' does not exist in the current context	C:\Users\Dan\AppData\Local\Temporary Projects\Sudoku Solver\Form1.cs	21	47	Sudoku Solver
"

It's probably me being the noob I am. :s

I assume you are using Visual Studio.
Make a form application. Put a TextBox control on the form.
Go to the code produced in ...Designer.cs and see how it is done.
Remove the textbox. Go to the form class and add the textbox variable as an array and fill in all the details you want in the constructor.(Just after InitializeComponent()) VS will not help you out here.

I assume you are using Visual Studio.
Make a form application. Put a TextBox control on the form.
Go to the code produced in ...Designer.cs and see how it is done.
Remove the textbox. Go to the form class and add the textbox variable as an array and fill in all the details you want in the constructor.(Just after InitializeComponent()) VS will not help you out here.

I don't understand what you mean by "add the textbox variable as an array" I have done what you said up until remove the textbox.

Use something like :
public TextBox[] MyTxBxArray = new TextBox[81];
or as a 2 dimensional array
public TextBox[,] MyTxBxArray2 = new TextBox[9,9];Keep in mind that this initializes the array not the TextBoxes! You still have to do that.

like:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace testst
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            TextBox[,] MyTxBxArray2 = new TextBox[9, 9];
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

     
    }
}

so then i do a loop assigning the value of each of the visual textboxes to the coded textboxes?

Not really.
Do it outside(after) InitializeComponent()
Never do it inside! All you want to do yourself must be done elsewhere.

public partial class Form1 : Form
    {
        public TextBox[,] MyTxBxArray2 = new TextBox[9,9];

        public Form1()
        {
            //init form
            InitializeComponent();
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    MyTxBxArray2[i, j] = new TextBox();
                    //MyTxBxArray2[i, j].Location = new System.Drawing.Point(function of i, function of j);
                    //MyTxBxArray2[i, j].Size = ...
                    //other properties of TextBox here

                }
            }

ah, you must not have seen my edit....

Firstly i get this error:

Error	1	'WindowsFormsApplication1.Form1' does not contain a definition for 'Form1_Load' and no extension method 'Form1_Load' accepting a first argument of type 'WindowsFormsApplication1.Form1' could be found (are you missing a using directive or an assembly reference?)	C:\Users\Dan\AppData\Local\Temporary Projects\WindowsFormsApplication1\Form1.Designer.cs	60	55	WindowsFormsApplication1

sorry i am completely new to this. So when you say

MyTxBxArray2[i, j] = new TextBox();

you are creating a textbox on the heap right? So those lines you have commented out:

//MyTxBxArray2[i, j].Location = new System.Drawing.Point(function of i, function of j);
                    //MyTxBxArray2[i, j].Size = ...

if you take away the comment marks you can create them on the form?

Best way to proceed : trash your project and start a new one.
It only contained a form and a textbox, right?
Start a new forms project.
Don't ever touch InitializeComponent(); again, VS maintains that for your convenience.
Now start to code after it.

//init a label, name it label1
private System.Windows.Forms.Label label1;
//instantiate a label
label1 = new System.Windows.Forms.Label();
//set properties
label1.Location = new System.Drawing.Point(100, 100);
label1.Name = "MyLabelText";
//add this control to the control collection of the form
Controls.Add(this.label1);

This is code for a Label control but it is the same for a TextBox array or whatever.
Run this code and change 100,100 to 10,10 and see what happens.

so i have this:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            //init a label, name it label1
 System.Windows.Forms.Label label1;
//instantiate a label
label1 = new System.Windows.Forms.Label();
//set properties
label1.Location = new System.Drawing.Point(100, 100);
label1.Name = "MyLabelText";
//add this control to the control collection of the form
Controls.Add(this.label1);
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}

and i get an error saying:

Error 1 'WindowsFormsApplication1.Form1' does not contain a definition for 'label1' and no extension method 'label1' accepting a first argument of type 'WindowsFormsApplication1.Form1' could be found (are you missing a using directive or an assembly reference?) C:\Users\Dan\AppData\Local\Temporary Projects\WindowsFormsApplication1\Form1.cs 25 19 WindowsFormsApplication1

all i have in my design is a textbox. If I add a label to the design then the error goes but nothing happens when running the program

Sorry about it but lines 18 and 19 should be before public Form1()
But I wonder... do you ever compile?
Do you think I am the great C# guru who knows everything about it? No! Why are you repeating my code samples? You want to code a sudoku game aren't you? Try to figure out as much of the TextBox array as you can for yourself.
Any questions? Just ask them... Stupid questions don't exist, stupid answers do...

Stupid questions don't exist

They so do exist.

"Then why does it taste so salty?"

:icon_eek: There's a lot of stuff flying around here.

OK, here's some code to get the grid of TextBoxes displayed, and a button that shows some basic interaction:

Put this at the top of your form's class:

TextBox[,] tb = null;

Put this into your Form_Load():

tb = new TextBox[9,9];

for (int i = 0; i < 9; i++)
{
    for (int j = 0; j < 9; j++)
    {
        tb[i, j] = new TextBox();
        tb[i, j].Visible = true;
        // These numbers are just a bit wider and taller than the text
        // box we're adding.  Feel free to goof with them to get the
        // look you want
        tb[i, j].Location = new Point(i * 41, j * 35) ;
        tb[i, j].Width = 40;
        this.Controls.Add(tb[i, j]);
    }
}

If you don't have a Form_Load(), you can get one by double-clicking on any blank area inside the form on the designer.

Drag a button onto the form, all the way to the right. Double click it and put this code into the button1_click() method (or whatever it's named):

for (int i = 0; i < 9; i++)
{
    for (int j = 0; j < 9; j++)
    {
        tb[i, j].Text = ((i * 9) + j).ToString();
    }
}

Some points:

The declaration of the array of text boxes must be global - you'll be accessing them later, so you can't declare it inside a method (like Form1()).

The button shows how you can access all of the text boxes. Also, you can get to any single text box if you know the row and column:

tb[4,3].Text = "Some Text";

would put text into the box at the 5th column, 4th row.

Hopefully, this should get you started. Good luck!

ah, i'd just done it like this, having not seen your post:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
  
    public partial class Form1 : Form
    {
        int[,] main = new int[9, 9] ;
        

      
        public Form1()
        {

            InitializeComponent();
                      
            }
        
        private void btnInput_Click(object sender, EventArgs e)
        {
           
            if (txt00.Text != "") {main[0, 0] = Convert.ToInt32(txt00.Text);} else {main[0,0] = 0;}
            if (txt01.Text != "") {main[0, 1] = Convert.ToInt32(txt01.Text);}else {main[0,1] = 0;}
            if (txt02.Text != "") {main[0, 2] = Convert.ToInt32(txt02.Text);}else {main[0,2] = 0;}
            if (txt03.Text != "") {main[0, 3] = Convert.ToInt32(txt03.Text);}else {main[0,3] = 0;}
            if (txt04.Text != "") {main[0, 4] = Convert.ToInt32(txt04.Text);}else {main[0,4] = 0;}
            if (txt05.Text != "") {main[0, 5] = Convert.ToInt32(txt05.Text);}else {main[0,5] = 0;}
            if (txt06.Text != "") {main[0, 6] = Convert.ToInt32(txt06.Text);}else {main[0,6] = 0;}
            if (txt07.Text != "") {main[0, 7] = Convert.ToInt32(txt07.Text);}else {main[0,7] = 0;}
            if (txt08.Text != "") {main[0, 8] = Convert.ToInt32(txt08.Text);}else {main[0,8] = 0;}


            if (txt10.Text != "") { main[1, 0] = Convert.ToInt32(txt10.Text); } else { main[1, 0] = 0; }
            if (txt11.Text != "") { main[1, 1] = Convert.ToInt32(txt11.Text); } else { main[1, 1] = 0; }
            if (txt12.Text != "") { main[1, 2] = Convert.ToInt32(txt12.Text); } else { main[1, 2] = 0; }
            if (txt13.Text != "") { main[1, 3] = Convert.ToInt32(txt13.Text); } else { main[1, 3] = 0; }
            if (txt14.Text != "") { main[1, 4] = Convert.ToInt32(txt14.Text); } else { main[1, 4] = 0; }
            if (txt15.Text != "") { main[1, 5] = Convert.ToInt32(txt15.Text); } else { main[1, 5] = 0; }
            if (txt16.Text != "") { main[1, 6] = Convert.ToInt32(txt16.Text); } else { main[1, 6] = 0; }
            if (txt17.Text != "") { main[1, 7] = Convert.ToInt32(txt17.Text); } else { main[1, 7] = 0; }
            if (txt18.Text != "") { main[1, 8] = Convert.ToInt32(txt18.Text); } else { main[1, 8] = 0; }

            if (txt20.Text != "") { main[2, 0] = Convert.ToInt32(txt20.Text); } else { main[2, 0] = 0; }
            if (txt21.Text != "") { main[2, 1] = Convert.ToInt32(txt21.Text); } else { main[2, 1] = 0; }
            if (txt22.Text != "") { main[2, 2] = Convert.ToInt32(txt22.Text); } else { main[2, 2] = 0; }
            if (txt23.Text != "") { main[2, 3] = Convert.ToInt32(txt23.Text); } else { main[2, 3] = 0; }
            if (txt24.Text != "") { main[2, 4] = Convert.ToInt32(txt24.Text); } else { main[2, 4] = 0; }
            if (txt25.Text != "") { main[2, 5] = Convert.ToInt32(txt25.Text); } else { main[2, 5] = 0; }
            if (txt26.Text != "") { main[2, 6] = Convert.ToInt32(txt26.Text); } else { main[2, 6] = 0; }
            if (txt27.Text != "") { main[2, 7] = Convert.ToInt32(txt27.Text); } else { main[2, 7] = 0; }
            if (txt28.Text != "") { main[2, 8] = Convert.ToInt32(txt28.Text); } else { main[2, 8] = 0; }

            if (txt30.Text != "") { main[3, 0] = Convert.ToInt32(txt30.Text); } else { main[3, 0] = 0; }
            if (txt31.Text != "") { main[3, 1] = Convert.ToInt32(txt31.Text); } else { main[3, 1] = 0; }
            if (txt32.Text != "") { main[3, 2] = Convert.ToInt32(txt32.Text); } else { main[3, 2] = 0; }
            if (txt33.Text != "") { main[3, 3] = Convert.ToInt32(txt33.Text); } else { main[3, 3] = 0; }
            if (txt34.Text != "") { main[3, 4] = Convert.ToInt32(txt34.Text); } else { main[3, 4] = 0; }
            if (txt35.Text != "") { main[3, 5] = Convert.ToInt32(txt35.Text); } else { main[3, 5] = 0; }
            if (txt36.Text != "") { main[3, 6] = Convert.ToInt32(txt36.Text); } else { main[3, 6] = 0; }
            if (txt37.Text != "") { main[3, 7] = Convert.ToInt32(txt37.Text); } else { main[3, 7] = 0; }
            if (txt38.Text != "") { main[3, 8] = Convert.ToInt32(txt38.Text); } else { main[3, 8] = 0; }

            if (txt40.Text != "") { main[4, 0] = Convert.ToInt32(txt40.Text); } else { main[4, 0] = 0; }
            if (txt41.Text != "") { main[4, 1] = Convert.ToInt32(txt41.Text); } else { main[4, 1] = 0; }
            if (txt42.Text != "") { main[4, 2] = Convert.ToInt32(txt42.Text); } else { main[4, 2] = 0; }
            if (txt43.Text != "") { main[4, 3] = Convert.ToInt32(txt43.Text); } else { main[4, 3] = 0; }
            if (txt44.Text != "") { main[4, 4] = Convert.ToInt32(txt44.Text); } else { main[4, 4] = 0; }
            if (txt45.Text != "") { main[4, 5] = Convert.ToInt32(txt45.Text); } else { main[4, 5] = 0; }
            if (txt46.Text != "") { main[4, 6] = Convert.ToInt32(txt46.Text); } else { main[4, 6] = 0; }
            if (txt47.Text != "") { main[4, 7] = Convert.ToInt32(txt47.Text); } else { main[4, 7] = 0; }
            if (txt48.Text != "") { main[4, 8] = Convert.ToInt32(txt48.Text); } else { main[4, 8] = 0; }

            if (txt50.Text != "") { main[5, 0] = Convert.ToInt32(txt50.Text); } else { main[5, 0] = 0; }
            if (txt51.Text != "") { main[5, 1] = Convert.ToInt32(txt51.Text); } else { main[5, 1] = 0; }
            if (txt52.Text != "") { main[5, 2] = Convert.ToInt32(txt52.Text); } else { main[5, 2] = 0; }
            if (txt53.Text != "") { main[5, 3] = Convert.ToInt32(txt53.Text); } else { main[5, 3] = 0; }
            if (txt54.Text != "") { main[5, 4] = Convert.ToInt32(txt54.Text); } else { main[5, 4] = 0; }
            if (txt55.Text != "") { main[5, 5] = Convert.ToInt32(txt55.Text); } else { main[5, 5] = 0; }
            if (txt56.Text != "") { main[5, 6] = Convert.ToInt32(txt56.Text); } else { main[5, 6] = 0; }
            if (txt57.Text != "") { main[5, 7] = Convert.ToInt32(txt57.Text); } else { main[5, 7] = 0; }
            if (txt58.Text != "") { main[5, 8] = Convert.ToInt32(txt58.Text); } else { main[5, 8] = 0; }

            if (txt60.Text != "") { main[6, 0] = Convert.ToInt32(txt60.Text); } else { main[6, 0] = 0; }
            if (txt61.Text != "") { main[6, 1] = Convert.ToInt32(txt61.Text); } else { main[6, 1] = 0; }
            if (txt62.Text != "") { main[6, 2] = Convert.ToInt32(txt62.Text); } else { main[6, 2] = 0; }
            if (txt63.Text != "") { main[6, 3] = Convert.ToInt32(txt63.Text); } else { main[6, 3] = 0; }
            if (txt64.Text != "") { main[6, 4] = Convert.ToInt32(txt64.Text); } else { main[6, 4] = 0; }
            if (txt65.Text != "") { main[6, 5] = Convert.ToInt32(txt65.Text); } else { main[6, 5] = 0; }
            if (txt66.Text != "") { main[6, 6] = Convert.ToInt32(txt66.Text); } else { main[6, 6] = 0; }
            if (txt67.Text != "") { main[6, 7] = Convert.ToInt32(txt67.Text); } else { main[6, 7] = 0; }
            if (txt68.Text != "") { main[6, 8] = Convert.ToInt32(txt68.Text); } else { main[6, 8] = 0; }

            if (txt70.Text != "") { main[7, 0] = Convert.ToInt32(txt70.Text); } else { main[7, 0] = 0; }
            if (txt71.Text != "") { main[7, 1] = Convert.ToInt32(txt71.Text); } else { main[7, 1] = 0; }
            if (txt72.Text != "") { main[7, 2] = Convert.ToInt32(txt72.Text); } else { main[7, 2] = 0; }
            if (txt73.Text != "") { main[7, 3] = Convert.ToInt32(txt73.Text); } else { main[7, 3] = 0; }
            if (txt74.Text != "") { main[7, 4] = Convert.ToInt32(txt74.Text); } else { main[7, 4] = 0; }
            if (txt75.Text != "") { main[7, 5] = Convert.ToInt32(txt75.Text); } else { main[7, 5] = 0; }
            if (txt76.Text != "") { main[7, 6] = Convert.ToInt32(txt76.Text); } else { main[7, 6] = 0; }
            if (txt77.Text != "") { main[7, 7] = Convert.ToInt32(txt77.Text); } else { main[7, 7] = 0; }
            if (txt78.Text != "") { main[7, 8] = Convert.ToInt32(txt78.Text); } else { main[7, 8] = 0; }

            if (txt80.Text != "") { main[8, 0] = Convert.ToInt32(txt80.Text); } else { main[8, 0] = 0; }
            if (txt81.Text != "") { main[8, 1] = Convert.ToInt32(txt81.Text); } else { main[8, 1] = 0; }
            if (txt82.Text != "") { main[8, 2] = Convert.ToInt32(txt82.Text); } else { main[8, 2] = 0; }
            if (txt83.Text != "") { main[8, 3] = Convert.ToInt32(txt83.Text); } else { main[8, 3] = 0; }
            if (txt84.Text != "") { main[8, 4] = Convert.ToInt32(txt84.Text); } else { main[8, 4] = 0; }
            if (txt85.Text != "") { main[8, 5] = Convert.ToInt32(txt85.Text); } else { main[8, 5] = 0; }
            if (txt86.Text != "") { main[8, 6] = Convert.ToInt32(txt86.Text); } else { main[8, 6] = 0; }
            if (txt87.Text != "") { main[8, 7] = Convert.ToInt32(txt87.Text); } else { main[8, 7] = 0; }
            if (txt88.Text != "") { main[8, 8] = Convert.ToInt32(txt88.Text); } else { main[8, 8] = 0; }



        }

      
     
        }
    }

does it make a difference which one i use do you think?

That code

is awful.

I would so make fun of you for that.

Show the code that defines the variables txt00 through txt88, so that we can put them in an array.

Well, checking your boxes for user input will be a chore. Having the controls in an array would help with that.

That code

is awful.

I would so make fun of you for that.

Show the code that defines the variables txt00 through txt88, so that we can put them in an array.

but that's the point. Look at my original question.... its how do you do this more simply? Lol I know it's stupid hence why i asked.

The code that defines the variables txt00 through txt88 doesn't exist because they are defined within the design of the form..

so coming back to Mike's post. Thanks for the code btw. I have changed the code to:

tb[i, j].Location = new Point((i + 1)* 41, (j + 1) * 35);
tb[i, j].Width = 30;

as you suggested so it looks a bit better...

Here is my new code then:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace etet
{
    public partial class Form1 : Form
    {
        TextBox[,] tb = null;
        int[,] main = new int[9, 9];
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            tb = new TextBox[9, 9];

            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    tb[i, j] = new TextBox();
                    tb[i, j].Visible = true;
                    // These numbers are just a bit wider and taller than the text
                    // box we're adding.  Feel free to goof with them to get the
                    // look you want
                    tb[i, j].Location = new Point((i + 1)* 41, (j + 1) * 35);
                    tb[i, j].Width = 30;
                    this.Controls.Add(tb[i, j]);
                }
            }
        }

        public void btnInput_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    if (tb[i, j].Text != "") { main[i, j] = Convert.ToInt32(tb[i, j].Text); } else { main[i, j] = 0; }
                    
                }
            }
        }
    }
}

is there actually any point in making a new array to import the user data or should i just work with the textbox array? Or I suppose that won't really work as it's not an integer array...

Copied a line of your "code":
if (txt68.Text != "") { main[6, 8] = Convert.ToInt32(txt68.Text); } else { main[6, 8] = 0; }
Do you notice any similarity between main[6, 8] and txt68.Text?

I'd do a separate array.

Copied a line of your "code":
if (txt68.Text != "") { main[6, 8] = Convert.ToInt32(txt68.Text); } else { main[6, 8] = 0; }
Do you notice any similarity between main[6, 8] and txt68.Text?

sorry what?

I've adopted Mike's code now anyway. And yes, txt68 is (was) the textbox that coincided with position 6,8 in the array.

Sorry my post came a bit late in the discussion here, carry on db11 you are on a way.

Well, I suppose we can consider this solved as the original question is answered. I'll undoubtedly encounter other problems in this particular project but I'll make a new thread for them.

Thanks everyone for the help (especially Mike ;).

Don't know if you figured it out but check out my topic, I had the exact same problem with my code (looping through all the textboxes):
http://www.dreamincode.net/forums/index.php?showtopic=45008&hl=

Specifically this is the code you're looking for:

for (int i = 1; i <= 48; i++)
{
       Label label = (Label)Controls["label" + i];
       if (label.Text == numllamados[1])
       label.BackColor = Color.GreenYellow;
}

What it does it create a label object to cycle through everything and then checks if the .Text of said object is equal to one of my values.
If it is equal, change the .BackColor to .Color.GreenYellow

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.