-1

I can not display the Text property of a TextBox that I created using code. I created the textbox using TextBox newTextBox = new TextBox() but MessageBox(newTextBox.Text) gives error.

Here is the code I talked about:

var name = String.Format("R{0}C{1}B{2}", row, column, box); 
TextBox newTextBox = (TextBox)Controls.Find(name, true).FirstOrDefault();      
MessageBox.Show(newTextBox.Text); 

P.S. I have textbox that are name R1C1B1, `R1C2B1`` and so on!


Error Message:

An unhandled exception of type 'System.NullReferenceException' occurred in SudokuSolver.exe

Additional information: Object reference not set to an instance of an object.
Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
Domoq
  • 25
  • 2
  • 7
  • 1
    What do you mean by "Cannot read text from a manually created TextBox control" - does it throw an exception or shows empty string? And it is better to use `First` rather than `FirstOrDefault` - http://stackoverflow.com/questions/1024559/when-to-use-first-and-when-to-use-firstordefault-with-linq in your case, because if `Find` fails - the `newTextBox` will be null. – Eugene Podskal Aug 20 '14 at 18:43
  • 3
    Your code is correct.Make sure that the textbox is on the form and not inside another container (like a panel) – George Vovos Aug 20 '14 at 18:50
  • From where you you run the code? Have you tried it from a Button? – TaW Aug 20 '14 at 19:01
  • I do run it from a button and the textboxes are on the form – Domoq Aug 20 '14 at 19:18
  • did my solution solve your problem? if it solved please mark my solution as answer so that others could benefit :) – nevets Aug 27 '14 at 20:32

2 Answers2

1

I suspect your Textbox is actually within some other containers, like a Panel.

Try to find your control using a recursive approach:

public static Control FindTargetTextbox(Control control, string targetName)
{
    foreach (Control child in control.Controls)
    {
        if (child is TextBox && child.Name == targetName)
        {
            return child;
        }
    }

    foreach (Control child in control.Controls)
    {
        Control target = FindTargetComponent(child);

        if (target != null)
        {
            return target;
        }
    }

    return null;
}

Bear in mind that your form is the biggest container, therefore you should pass it in as the starting point:

TextBox textBox = FindTargetTextbox(this, name);

Edit As @mikeng mentioned in the comment, we are able to merge two foreach into one like this:

public static Control FindTargetTextbox(Control control, string targetName)
{
    foreach (Control child in control.Controls)
    {
        if (child is TextBox && child.Name == targetName)
        {
            return child;
        }

        Control target = FindTargetComponent(child);

        if (target != null)
        {
            return target;
        }
    }

    return null;
}

This is indeed another valid approach, but one should choose the most appropriate approach based on the real situation:

The first approach explores all controls in the same container before it goes deep into a child control of that container, which is a Breadth First Search, while the second approach focuses on nested controls one by one, i.e. it goes to next container only after it finishes processing all controls in the current container, which is a Depth First Search.

nevets
  • 4,631
  • 24
  • 40
  • Nice recursive method, but why not merge the two foreach statements into one ? – Mikael Engver Aug 20 '14 at 20:11
  • 1
    @mikeng it's just another implementation. if you merge them up, you will need to go to the deepest of a container then another, but split them will exam all controls inside 1 container, then go deep. – nevets Aug 21 '14 at 02:24
0

As i said your is correct so

1)The isn't a textbox with the specified name
2)There is a textbox but it is inside a container

In any case,use this code to find which controls exist on your form and then call the Find method from the correct container

foreach (Control item in this.Controls)
{
            if (item is TextBox)
                Console.WriteLine("TextBox:" + item.Name);
            else
                Console.WriteLine(item.GetType().Name + ":" + item.Name);

}

George Vovos
  • 7,563
  • 2
  • 22
  • 45