Storing string values in array then displaying the array values - c#

I’m a student working on a class project to store string values into an array[10] using a “Store” button. Then the “Display” button will display the string values in the array[10] in a list box. Extra credit if we display the position too.
Currently when I click the “Store” button I do see the message the value was stored. But when I click the “Display” button the list box shows 10 “0”. Every time I make it only makes it worse so I’m not sure what I’m missing and overlooking.
My global variables
string[] results = new string[10];
string value;
I’m using the for loop to take the string value in the “ResultLabel” to store them in the array[10] until all spaces are take, total of 10 values. The “StoreLabel” displays the message that the value was stored.
protected void StoreButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < results.Length; i++)
{
results[i] = ResultLabel.Text.ToString();
}
StoreLabel.Text = "Results have been stored";
}
Then I believe I’m taking the values from the results[10] array and displaying those values in the list box.
protected void DisplayButton_Click(object sender, EventArgs e)
{
DisplayListBox.Items.Clear();
for (int i = 0; i < results.Length; i++)
{
DisplayListBox.Items.Add(results[i].ToString());
}
}

You can append the index to string.
private void StoreButton_Click(object sender, EventArgs e)
{
for (int i = 0; i < results.Length; i++)
{
results[i] = ResultLabel.Text.ToString();
}
StoreLabel.Text = "Results have been stored";
}
private void DisplayButton_Click(object sender, EventArgs e)
{
DisplayListBox.Items.Clear();
for (int i = 0; i < results.Length; i++)
{
DisplayListBox.Items.Add($"{results[i].ToString()} - {i}");
}
}

I understand your project requires you to use an array and to limit it to 10 items. Those requirements might be simplified if we let the ListBox do all the hard work. I'd like to offer an easy way to get strings into the ListBox with the idea that you can then adapt this strategy to meet your project requirements.
The ListBox is simple to work with if we tell it to use our list as the source of the items it displays. Then all we have to do is add an item to this list and tell the ListBox to Refresh() its contents.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listBoxDisplay.DataSource = Values;
}
// Here is our list of strings
BindingList<string> Values = new BindingList<string>();
private void buttonStore_Click(Object sender, EventArgs e)
{
// We look at the value in the textbox and add it to list...
Values.Add((Values.Count + 1).ToString() + " - " + textBoxValueToAdd.Text);
// …and tell the ListBox to update itself from the list
listBoxDisplay.Refresh();
}
}

Related

Looping Through C# Textboxes

I'm trying to have the user input doubles into 4 different textBoxes. Then, once the user clicks the calculate button, the following will happen:
foreach loop runs, parses textbox.Texts to doubles, and then adds
them to a list
for loop runs and indexes through the list, adding
them all up.
List item sum from previous step is divided by the number of values in the list result is entered into another textbox.
When I run it, no errors happen, but the result is not displayed in the texbox. Why is nothing getting displayed?
private void CalculateButton_Click(object sender, EventArgs e)
{
double gpa = 0;
List<double> grades = new List<double>();
foreach(Control textBox in Controls)
{
if ((textBox.GetType().ToString() == "System.Windows.Form.Textbox") && (textBox.Name.Contains("gradeBox")))
{
grades.Add(double.Parse(textBox.Text));
}
}
for(int i =0; i<grades.Count; i++)
{
gpa += grades[i];
}
gpa /= grades.Count;
gpaBox.Text = gpa.ToString();
}
Looks like the namespace of textbox is not quite correct. It should be System.Windows.Forms.TextBox. Notice "s" and capital "B". Following is the corrected version.
private void CalculateButton_Click(object sender, EventArgs e)
{
double gpa = 0;
List<double> grades = new List<double>();
foreach (Control textBox in Controls)
{
if ((textBox.GetType().ToString() == "System.Windows.Forms.TextBox") && (textBox.Name.Contains("gradeBox")))
{
grades.Add(double.Parse(textBox.Text));
}
}
for (int i = 0; i < grades.Count; i++)
{
gpa += grades[i];
}
gpa /= grades.Count;
gpaBox.Text = gpa.ToString();
}

C# Array input from windows form textbox

I am currently working on a homework assignment that I am struggling with. The goal of the program is to:
Create a program that allows users to record and view names of up to 1000 events. The names of the events are to be stored in an array. The names can be stored and viewed sequentially only: I,e, the first time the user presses “Set” to store a name, it would be placed in index 0 of the array; the second time the user stores a name it would be stored in index 1, etc. Similarly, the first time the user presses “View”, the item found in index 0 of the array is shown to the user; the second time the user presses “View”, the item found in index 1 of the array is shown, etc.
When the user presses the “Set” button (btnSet), an event name is inserted into the array in the next free index, sequentially as described above. The name to insert to the array is taken from txtEventName.
When the user presses the button “View” (btnView), the name of the next event to view sequentially (as described above) is shown to the user. The event name is shown to the user in txtName.
I currently have the code:
namespace ArrayHW
{
public partial class Form1 : Form
{
int[] eventsArray;
const int SIZE = 1000;
public Form1()
{
InitializeComponent();
}
private void btnSet_Click(object sender, EventArgs e)
{
eventsArray = new int[SIZE];
for (int index = 0; index < eventsArray.Length - 1; index++)
{
eventsArray[index] = Convert.ToInt32(txtEventName.Text);
}
}
private void btnView_Click(object sender, EventArgs e)
{
for (int index = 0; index < eventsArray.Length- 1; index++)
{
Debug.WriteLine(eventsArray[index]);
txtName.Text = Convert.ToString(eventsArray[index]);
}
}
}
}
When I run the form, I only get the result for index = 0,1, 2, 3, etc or whatever I had just input into the array in
private void btnSet_Click(object sender, EventArgs e)
{
eventsArray = new int[SIZE];
for (int index = 0; index < eventsArray.Length - 1; index++)
{
eventsArray[index] = Convert.ToInt32(txtEventName.Text);
}
}
rather than it showing up in sequential order like it is supposed to. Could anyone show me a better way to approach this problem, or help me find out what I am doing wrong? Thank you very much.
Please read the comments in the code block. Hopefully that will help you resolve your problem.
public partial class Form1 : Form
{
const int SIZE = 1000;
int[] eventsArray = new int[SIZE];
//as per your requirement, you would need these
//to display and set items at proper index in the array.
int _setIndex = 0;
int _viewIndex = 0;
public Form1()
{
InitializeComponent();
}
private void btnSet_Click(object sender, EventArgs e)
{
//this is where your problem is. Every time the Set btn is clicked,
//you are creating a new array. Therefore you are only seeing what you added in the
//last click. Anything that was added to the array on the prior clicks are lost because
//you just created a new array with the line below.
//eventsArray = new int[SIZE];
//You would need to comment the line above because this is code block is being
//executed on every btnSet click. New up this array only once by moving this to global scope.
//for (int index = 0; index < eventsArray.Length - 1; index++)
//{
// eventsArray[index] = Convert.ToInt32(txtEventName.Text);
//}
//Since we have created fields to keep track of _setIndex, all we need to do is:
if (_setIndex < SIZE)
{
eventsArray[_setIndex] = Convert.ToInt32(txtEventName.Text);
_setIndex++;
}
}
private void btnView_Click(object sender, EventArgs e)
{
//this wont be necessary.
//for (int index = 0; index < eventsArray.Length - 1; index++)
//{
// Debug.WriteLine(eventsArray[index]);
// txtName.Text = Convert.ToString(eventsArray[index]);
//}
if(eventsArray.Length > _viewIndex)
{
txtName.Text = Convert.ToString(eventsArray[_viewIndex]);
//this is to fulfill the requirement below:
// Similarly, the first time the user presses “View”, the item found in index 0
// of the array is shown to the user; the second time the user presses “View”,
// the item found in index 1 of the array is shown, etc.
_viewIndex++;
}
}
}
Try this:
int[] eventsArray = new int[SIZE];
int index = 0;
const int SIZE = 1000;
private void btnSet_Click(object sender, EventArgs e)
{
eventsArray[index++] = Convert.ToInt32(txtEventName.Text);
}

C# Windows Form - How can I call array initialized in click method to other parts of the form

How can I call this array that initializes on a button click event:
private void button1_Click(object sender, EventArgs e)
{
int[] n = textBox1.Text.Split(' ').Select(int.Parse).ToArray();
richTextBox1.Text += "Entered values: ";
foreach (int num in n)
{
richTextBox1.Text += num + " ";
}
richTextBox1.Text += "\n";
}
to other parts of an array, say another click event.
I have tried declaring the array in the form class but that requires the array to have a pre-defined size which is problematic for other parts of the code.
EDIT: Solved! Thanks to the guys at stackoverflow. Solutions and comments were very helpful :D
You can declare the array in the Form's class without specifying its dimensions simply like this:
int[] n = null; //choose better name, and comment the use of the variable.
The rest of the methods (such as click event handlers) can use it like this:
private void someOtherButton_Click(object sender, EventArgs e)
{
if(n != null && n.Length > 0)
{
//do something with the array
}
}
You have to make the array to a field (You can initialize the array with the size 0, if that's a problem for your program you have to overthink the rest of your code). It would look like this then:
private int[] n = new int[0];
private void button1_Click(object sender, EventArgs e)
{
n = textBox1.Text.Split(' ').Select(int.Parse).ToArray();
By the way, I'd strongly suggest not to call the array 'n' but a meaningful name (e.g. _splittedTb1Content).
Use Generics collection type instead :
private void button1_Click(object sender, EventArgs e)
{
List<int> n= textBox1.Text.Split(' ').Select(int.Parse).ToList();
richTextBox1.Text += "Entered values: ";
foreach (int num in n)
{
richTextBox1.Text += num + " ";
}
richTextBox1.Text += "\n";
}
You can declare list n in your form class:
List<int> n;
I also recommend use stringBuilder inside your "foreach" to improve performance for longer list. Use following code if you are processing a longer list.
private void button1_Click(object sender, EventArgs e)
{
List<int> n= textBox1.Text.Split(' ').Select(int.Parse).ToList();
var sBuilder = new StringBuilder();
sBuilder.Append("Entered values: ");
foreach (int num in n)
{
sBuilder.Append(num + " ");
}
sBuilder.AppendLine();
richTextBox1.Text += sBuilder.ToString();
}

Use loop to clear. textBox[i].Clear(). Is this possible?

I am just looking to know this to try and clean up my code, and also for future reference.
I have a number of textBoxes.
tbPart1.Clear();
tbPart2.Clear();
tbPart3.Clear();
tbPart4.Clear();
tbPart5.Clear();
tbPart6.Clear();
tbPart7.Clear();
Is there any way I could use a loop to replace the numbers?
I tried this, but have no idea how i could run the string.
for (int i = 1; i == 7; i++)
{
string p = "tbPart" + i.ToString() + ".Clear";
}
Inside of the form's code (i.e. in a button click event handler), you can enumerate through all of the TextBox controls on the form and perform a specific action on them:
this.Controls.OfType<TextBox>().ToList().ForEach(x => x.Clear());
If you need to only clear some of the TextBox controls, you can provide a sort of filter like so:
this.Controls.OfType<TextBox>()
// Add a condition to clear only some of the text boxes - i.e. those named "tbPart..."
.Where(x=>x.Name.StartsWith("tbPart"))
.ToList().ForEach(x => x.Clear());
No, you cannot do it that way. But you can define an array or list where you put the controls and then clear them. For example:
List<TextBox> textboxes = new List<TextBox>();
textboxes.Add(tbPart1);
textboxes.Add(tbPart2);
textboxes.Add(tbPart3);
...
Then when you want to clear them
foreach (var tb in textboxes)
tb.Clear();
TextBox[] boxes = new [] {
tbPart1,
tbPart2,
tbPart3,
tbPart4,
tbPart5,
tbPart6,
tbPart7
};
for (int i = 0; i < boxes.Length; i++)
{
boxes[i].Clear();
}
i think you should use an array of textbox then you can do a loop depends the count of numbers of textboxes.
foreach(Control ctrl in this.Controls)
{
if(ctrl.GetType() == typeof(TextBox))
{
ctrl.Text = String.Empty;
}
}
Answer number one by using Control name inside panel1
private void button2_Click(object sender, EventArgs e)
{
string currentCtrlName;
for (int i = 0; i < panel1.Controls.Count; i++)
{
currentCtrlName = "textBox" + (i+1).ToString();
panel1.Controls[currentCtrlName].Text = "";
}
}
==================
Answer number one by using Control index as a child inside panel1
private void button2_Click(object sender, EventArgs e)
{
for (int i = 0; i < panel1.Controls.Count; i++)
{
panel1.Controls[i].Text = "";
}
}
==================

How to fix this IndexOutOfBoundsException

My program runs fine, but there is a little problem. When I add new tracks previously existing file to the ListBox, the program experiences an error. The code seems unwilling to do looping in a new file which was added in a different time. Please help me. Thanks ....
public partial class Form1 : Form
{
//...
string[] files, paths;
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
files = openFileDialog1.SafeFileNames;
paths = openFileDialog1.FileNames;
for (int i = 0; i < files.Length - 1; i++)
{
listBox1.Items.Add(files[i]);
}
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
axWindowsMediaPlayer1.URL = paths[listBox1.SelectedIndex];
}
}
Adil has caught the cause of the problem, but there's a cleaner solution:
foreach (string file in files)
{
listBox1.Items.Add(file);
}
... or even better:
listBox1.Items.AddRange(files);
In fact, I'd go even further still, and get rid of the instance variables files and paths completely. I'd either use a Tuple<string, string> or create a class for the file/class pair. Then you can add each complete data item to listBox1.Items, set the DisplayMember so that the file part is displayed, but when the selected index is changed, fetch the path from the selected item. Then there's no need to mess around with indexes at all.
You are adding one file less then the files exists, When you will access the last
Change
for (int i = 0; i < files.Length - 1; i++)
{
listBox1.Items.Add(files[i]);
}
To
for (int i = 0; i < files.Length; i++)
{
listBox1.Items.Add(files[i]);
}
Edit based on comments by OP
You might be adding the files in listbox more then once by clicking button1. This will add new files in listbox but the arrays will loose previous items in the array and the count in array will become less then the items in listbox.
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Clear(); //Clear the items of list box to keep the same items in both listbox and in array paths.
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
files = openFileDialog1.SafeFileNames;
paths = openFileDialog1.FileNames;
for (int i = 0; i < files.Length ; i++)
{
listBox1.Items.Add(files[i]);
}
}
}
If you want to keep the previous selection then use list instead of arrays as list can grow more easily then the array.
string[] files;
List<string> paths = new List<string>() ;
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
files = openFileDialog1.SafeFileNames;
paths.AddRange(openFileDialog1.FileNames.ToList());
for (int i = 0; i < files.Length; i++)
{
listBox1.Items.Add(files[i]);
}
}
}
I don't think the problem is with adding items to the array. The more likely cause is the SelectedIndexChanged event handler. You should bounds check SelectedIndex to be sure it is valid.
int idx = listBox1.SelectedIndex;
if (paths != null && idx > 0 && idx < paths.Length)
{
axWindowsMediaPlayer1.URL = paths[idx];
}
I think both Jon and Adil are absolutely correct and you can definitely use their code to fix part of the problem. But, my guess is that you don't have any elements in paths and so when you try to get an element from it, it throws you an exception. Can you try the following code:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (paths.Length >= listBox1.SelectedIndex)
axWindowsMediaPlayer1.URL = paths[listBox1.SelectedIndex];
}
See if you're still thrown an exception and if not, then you have another problem of why your paths variable is not being set or why the listbox selected index is greater than the elements in the variable.

Categories