Click here to Skip to main content
15,885,366 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have this code. I want all the number are printed out on textbox, but there is only the last number is printed.


C#
private void btnDeal_Click(object sender, EventArgs e)
        {
            
            int[] numbers = { 9, 8, 7, 6 };
            for (int i = 0; i != numbers.Length; i++)
            {                
                int num = numbers[i];
                txtNorth.Text = num.ToString();
                i++;
            }

        }



How to print all number to textbox.

thanks,
Posted

OK, let's point out all bugs:

C#
private void btnDeal_Click(object sender, EventArgs e) //not a bug but violation of naming conventions
        {
            int[] numbers = { 9, 8, 7, 6 }; //hard-coded
            //no need to use for cycler, foreach is simpler, and i is not needed
            for (int i = 0; i != numbers.Length; i++) //bad variable name, use < numbers.Length instead
            {                
                int num = numbers[i]; 
                txtNorth.Text = num.ToString(); //data from old iterations is lost
                i++; //incremented again; don't operate cycle variable!
            } 
}


Fixed:
C#
static readonly int[] numbers = { 9, 8, 7, 6 };
static string delimiter = " "; //never use immediate constants, only use explicit constants

//..

btnDeal.Click += (sender, eventArgs) => { //anonymous delegate is the best
    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    foreach(int number in numbers) {
        sb.Append(number.ToString());
        sb.Append(delimiter);
    }
    txtNorth.Text = sb.ToString().Trim(); //trim to remove last delimiter
} //btnDeal.Click


This is a variant of delegate method for C# v.2 where lambda syntax was not yet introduced:

C#
btnDeal.Click += delegate(object sender, System.EventArgs eventArgs) { //explicitly declared types needed
    //... same as above
}
</pre>


Some explanation about Microsoft naming conventions: Yes, this name was generated by Microsoft, by Designer. So what? Who told that you're supposed to leave these names as is? You should renamed all auto-generated names into semantic names. The refactoring engine makes it easy. Do it, if you want to get maintainable code. I would recommend not creating event handlers with Designer at all (as I did above), but many don't like it. OK, but at least use semantic names.

Also, it makes no sense to show same thing on button click, potentially again and again, but I hope this is just for study of other techniques.

Good luck,
—SA
 
Share this answer
 
v4
Comments
Espen Harlinn 2-Nov-11 20:57pm    
Really good answer :)
Sergey Alexandrovich Kryukov 2-Nov-11 21:16pm    
Thank you, Espen.
--SA
DaveyM69 3-Nov-11 4:46am    
A couple of minor comments...
I don't like your method of blindly adding the deliminator even if it's not required and then creating an extra string by using Trim! Also, this will only take care of (with the parameterless Trim method), whitespace deliminators. You talk about maintainability, the deliminator requirement may change. This would be better IMO:

bool notFirst = false;
foreach(int number in numbers)
{
if(notFirst)
sb.Append(delimiter);
notFirst = true;
sb.Append(number.ToString());
}
txtNorth.Text = sb.ToString();

You say "//anonymous delegate is the best" - why? For readability and maintainability a good old method is far better IMO. It also allows for code reuse if needed as the method could be called from elsewhere.
Sergey Alexandrovich Kryukov 12-Jan-12 17:38pm    
I agree with your criticism about delimiter, thank you very much.

I disagree about anonymous. The method should have the name only when it is called by name. The maintainability is always better with anonymous: less names mean less renames during support/refactoring. :-)

As to the reuse: there is a better way to re-use -- with anonymous. The problem is: the handler usually has more parameters than the body of the handler uses. The usual parameters are sender and eventArgs, and one or both are not used. So, the reused method should be semantic, using only semantic parameter. An anonymous method should only prepare parameters and call this named method. I hope this is clear.

--SA
The problem is with assigning string to text box.
In current code when for loop iterates it will assign a new value from integer array to text box and old value is overwritten as is a reason for showing only last element of array. Also remove extra i++ statement at the end of code.

C#
private void btnDeal_Click(object sender, EventArgs e)
        {

            int[] numbers = { 9, 8, 7, 6 };
            for (int i = 0; i < numbers.Length; i++)
            {
                int num = numbers[i];
                txtNorth.Text += num.ToString() + " ";
            }

        }


Hope this help in rectifying error.
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 2-Nov-11 19:41pm    
I just had to vote 3 for use of "+=" for string in cycle, which is the incredible well-known performance "bug". Do you know that strings are immutable, so in each operation you get more and more data copied back and forth. In this example, you should use System.Text.StringBuilder, never "+=".
--SA
Usman Mahmood 3-Nov-11 17:21pm    
Thanks SAKryukov for pointing out using StringBuilder but the whole point is making code simple and understandable.
This code:
C#
txtNorth.Text = num.ToString();
overwrites the contents of the text each time the loop is called. You want something like:
C#
txtNorth.Text += num.ToString() + Environment.NewLine;
(assuming of course you want them all on different lines, if not replace Environment.NewLine with your desired separator).

Also, calling i++ at the end of the loop is unnecessary, the loop already does that (which is why the "for (int i = 0; i != numbers.Length; i++)" has i++ in it already)
 
Share this answer
 
v3
Comments
Sergey Alexandrovich Kryukov 2-Nov-11 19:41pm    
I just had to vote 3 for use of "+=" for string in cycle, which is the incredible well-known performance "bug". Do you know that strings are immutable, so in each operation you get more and more data copied back and forth. In this example, you should use System.Text.StringBuilder, never "+=".
--SA
lewax00 2-Nov-11 23:13pm    
I don't think the performance really matters for an array of 4 values. I'm just trying to keep it as simple as possible for the asker.
Hello,
Everything is fine there but u r checking with wrong condition..

use <= instead of !=
 
Share this answer
 
Comments
lewax00 2-Nov-11 18:08pm    
<= would call one beyond the bounds of the array. < would be fine, but != works as well, assuming you increment by 1 each time.
Sergey Alexandrovich Kryukov 2-Nov-11 19:42pm    
Really bad answer.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900