Microsoft Visual Studio Arrays at Runtime - c#

My instructions are: "Create a form that will display a running total of numbers a user enters." - to do this I've created a form with two text boxes (one for the number of values in the array and the other for the values in the array), a button to display it, and a label for it all to be displayed it. The issue is, is that my values aren't showing up - at all. My code is as below:
(** NOTE: I'm attempting to get the array to display in my label. txtInput is the inputted values and txtArrayValues is the number of elements.)
namespace Running_Total
{
public partial class frmEnter : Form
{
public frmEnter()
{
InitializeComponent();
}
private void btnDisplay_Click(object sender, EventArgs e)
{
int intNumber = Convert.ToInt32(txtArrayValues.Text);
string[] strArray;
strArray = new string[intNumber];
int i;
string j = "";
for (i = 0; i < intNumber; i++)
{
j = Convert.ToString(txtInput.Text);
strArray[i] += j;
}
lblDisplay.Text = strArray + " ";
}
}
}
Before, when I'd put lblDisplay.Text += j + " ";, it showed up in the label, but didn't pay any attention to the amount of elements the code was supposed to have. (Edit: this no longer works in my code.) (As is indicated in the title, I'm working with C# through Microsoft Visual Studio.)

It strongly depends on the fashion how the user inputs the numbers.
1) If he fills the textbox once with numbers and then presses the button to display them in the other box, it would suffice to use a string array catch the input and add it to the textbox or label that displays it. If he deletes the numbers in the input box and types new ones you could just repeat this step
namespace Running_Total
{
public partial class frmEnter : Form
{
// declare your Array here
string [] array = new string[1000];
int count = 0;
public frmEnter()
{
InitializeComponent();
}
private void btnDisplay_Click(object sender, EventArgs e)
{
// save input
array[count] = inputTextBox.Text;
count++;
// display whole input
string output = "";
for(int i = 0;i < count; i++)
{
output += array[i];
}
// write it the texbox
outputTextBox.Text = output;
}
}
Does that answer your question or do you have another input pattern in mind?

Looking at your code, I realized that you want to display same number enteted in txtInput text repeatedly up to as many times as a number entered in a txtArrayValues.Text. So for example txtArrayValues. Text = "5" and txtInput.Text="2", your code will yield result "2,2,2,2,2". If that is what you want then the following code will achieve that.
using System.Linq;
namespace Running_Total
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnDisplay_Click(object sender, EventArgs e)
{
int len, num;
if (int.TryParse(txtArrayValues.Text, out len) &&
int.TryParse(txtInput.Text, out num))
{
lblDisplay.Text = string.Join(",", new string[len].Select(x => txtInput.Text));
}
}
}
}

Related

WinForm Button stops working after 1-2 uses

I have a program that quizzes the user by naming a Country (from a list) and asks the user to input it's Capital. If they get it correct, a counter for correct answers is shown with +1 added to it. If it is wrong, the same thing goes but for the incorrect counter. I finished the code for it, but whenever I use the Check Answer button, it doesn't verify the input from the TextBox anymore, and none of the counters (correct or incorrect) change at all. If the first one is right and the second is wrong, it counts both 1 for correct and 1 for incorrect. After that the code under the Check Answer button doesn't execute anymore. If I got 2 right or 2 wrong it only counts the first 1 and stops working after.
{
// Declare structure
struct Country
{
// Declare strings
public string countryName;
public string capital;
}
public partial class Form1 : Form
{
// Create List for CourseInfo
private List<Country> countryList = new List<Country>();
Country currentCountry;
public Form1()
{
InitializeComponent();
}
private void ReadFile()
{
try
{
// Call StreamReader to use imported file
StreamReader inputFile;
string line;
Country entry = new Country();
// Delimiter to separate values in text file
char[] delim = { ',' };
// Open text file
inputFile = File.OpenText("countries.txt");
while (!inputFile.EndOfStream)
{
line = inputFile.ReadLine();
// Tokenize the strings separated by the delimiter ','
string[] tokens = line.Split(delim);
entry.countryName = tokens[0]; // Tokenized entry for COUNTRY
entry.capital = tokens[1]; // Tokenized entry for CAPITAL
countryList.Add(entry);
}
}
catch (Exception ex)
{
// Shows error message
MessageBox.Show(ex.Message);
}
}
private void DisplayCountry()
{
// Create random variable
Random rand = new Random();
// Country us randomly chosen from the list
int countryPosition = rand.Next(countryList.Count);
// Selected country
currentCountry = countryList[countryPosition];
// Show selected country in Label
countryAnswerLabel.Text = currentCountry.countryName;
}
private void ExitButton_Click(object sender, EventArgs e)
{
// Closes the form
this.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
// Call method to load StreamReader with the file
ReadFile();
}
private void QuizButton_Click(object sender, EventArgs e)
{
// Call method to show random country
DisplayCountry();
}
private void CheckAnswerButton_Click(object sender, EventArgs e)
{
// Declare integer variables for the counters and set to 0
int correctCounter = 0;
int incorrectCounter = 0;
// If the input is correct, +1 for the correct counter
if (currentCountry.capital == capitalAnswerTextBox.Text)
{
correctCounter++;
correctLabel.Text = correctCounter.ToString();
}
// If the input is incorrect, +1 for the incorrect counter
else
{
incorrectCounter++;
incorrectLabel.Text = incorrectCounter.ToString();
}
}
private void NextQuestionButton_Click(object sender, EventArgs e)
{
// Clears input TextBox
capitalAnswerTextBox.Text = string.Empty;
DisplayCountry();
}
}
Notice that whenever CheckAnswerButton_Click is executed, the variables correctCounter and incorrectCounter are initialised to 0. So every time you press the button, you start counting the answers from 0 again. So you will always be setting one of label's Text to "1". In case that label already shows "1", it would seem like it's "not doing anything".
Therefore, you should move the declarations of correctCount and incorrectCounter to outside the CheckAnswerButton_Click method:
// Declare integer variables for the counters and set to 0
int correctCounter = 0;
int incorrectCounter = 0;
private void CheckAnswerButton_Click(object sender, EventArgs e)
{
// If the input is correct, +1 for the correct counter
if (currentCountry.capital == capitalAnswerTextBox.Text)
{
correctCounter++;
correctLabel.Text = correctCounter.ToString();
}
// If the input is incorrect, +1 for the incorrect counter
else
{
incorrectCounter++;
incorrectLabel.Text = incorrectCounter.ToString();
}
}
This way, they will retain their value after CheckAnswerButton_Click has returned.

Using a generic method in a C# class

Here is my current code:
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Random random = new Random();
public int[] randomInt = new int[20];
public double[] randomDouble = new double[20];
public string searchKey;
public int intOrDouble; // 0 if int, 1 if double
public static int Search<T>(T[] inputArray, T key) where T : IComparable<T>
{
for (int i = 0; i < 20; i++)
{
if (inputArray[i].CompareTo(key) == 0)
{
return i;
}
}
return -1;
}
public Form1()
{
InitializeComponent();
}
private void randomIntGeneration_Click(object sender, EventArgs e)
{
randomNumbersTextBox.Clear(); // empty the textbox
intOrDouble = 0; // this is for knowing which parameter to send to search method
// generate 20 random integers and display them in the textbox
for (int i = 0; i < 20; ++i)
{
randomInt[i] = random.Next(0, 100);
randomNumbersTextBox.Text += randomInt[i].ToString() + " ";
}
}
private void randomDoubleGenerator_Click(object sender, EventArgs e)
{
randomNumbersTextBox.Clear(); // empty the textbox
intOrDouble = 1; // this is for knowing which parameter to send to search method
// generate 20 random doubles and display them in the textbox
for (int i = 0; i < 20; ++i)
{
randomDouble[i] = random.NextDouble() + random.Next(0, 100);
randomNumbersTextBox.Text += randomDouble[i].ToString() + " ";
}
}
private void searchArrayButton_Click(object sender, EventArgs e)
{
searchKey = searchKeyTextBox.Text;
if(intOrDouble == 0) // int array passed
{
resultsTextBox.Text = Search(randomInt, searchKey).ToString();
}
else
{
resultsTextBox.Text = Search(randomDouble, searchKey).ToString();
}
}
}
}
What i am trying to do is use this generic method. The GUI allows the user to generate a random array of either ints or doubles. I then want to use the Search method in the searchArrayButton_Click control to display whether or not the "searchKey" value entered is in the array. The error I am getting is "The type arguments for method 'Form1.Search(T[], T)' cannot be inferred from the usage. Try specifying the type arguments explicitly." They appear toward the bottom of the code when I try to call Search twice in the searchArrayButton_Click control.
You're trying to search an array of int or double values for a string. As a result, your call to Search has two arguments with two different types. That doesn't match the function signature.
You need to convert whatever is in that textbox into the value you are searching for, either an int or a double.
if(intOrDouble == 0) // int array passed
{
resultsTextBox.Text = Search(randomInt, int.Parse(searchKey)).ToString();
}
else
{
resultsTextBox.Text = Search(randomDouble, double.Parse(searchKey)).ToString();
}

How to get array data from one Click Method to another one

Don't think i could be any newer to coding, so please forgive me for whats about to be asked.
Im currently writing a program that lets the user enter a desired amount of random numbers to be generated by Random via textBox (lets say 15 --> you get 15 random numbers), ranging from 1 to 1000.
When hitting the Button A, those randomized Numbers will be saved in Zahlenarray[](-->with the length of the number entered in the textbox) and displayed in label1.Text.
Then there's a Button B, that, when clicked, should sort the Numbers from Zahlenarray[] via bubblesort and display them in label2.
My problem is now that the second Method (Button B_Click) doesnt have the contents of Zahlenarray from the Button A_Click Method.
Id like to pass this data by ref via the arguments, but fiddling with public void (Object sender, EventArgs e) seems to get me in major trouble.
Can i add arguments after EventArgs e, ... or am i missing another way of getting data out f this "scope" (hope thats the right word)?
Both Methods are in the same class.
part of the code of Button A:
public void Button_Anzeigen_Click(Object sender, EventArgs e)
{
label1.Text = "";
int[] Zahlenarray = new int[Int32.Parse(textBox1.Text)];
Everything from Button B:
private void Button_Sortieren_Click(object sender, EventArgs e)
{
label2.Text = "";
label3.Text = "";
int Speicher;
for (int n = Zahlenarray.Length; n > 0; n--)
{
for (int i = 0; i < n-1; i++)
{
if (Zahlenarray[i] > Zahlenarray[i + 1])
{
Speicher = Zahlenarray[i];
Zahlenarray[i] = Zahlenarray[i + 1];
Zahlenarray[i + 1] = Speicher;
Speicher = 0;
}
}
}
foreach (int i in Zahlenarray)
{
label2.Text += i + " ";
if ((i % 9 == 0) && !(i == 0))
label2.Text += "\n";
}
}
Put your array declaration outside of your buttona click handler so you can reference it inside your button b handler.
int[] Zahlenarray;
public void Button_Anzeigen_Click(Object sender, EventArgs e)
{
label1.Text = "";
Zahlenarray = new int[Int32.Parse(textBox1.Text)];
...
}

Converting strings to int in C#

im pretty new to C# and i want to make a cardgame. What i have is a list of cards (strings) with names like c6, s3, h11, d13 where the character represents the colour and the number represents the value. When pressing a button the program takes a random string from the list and displays it in a textbox. From there the point of the game is to guess if the next random card will have a higher value or a lower value then the previous card.
What i want to do is to take the string from the textbox and turn it into a int so that i can compare the value of the previous card with the new one. Only problem is how do i get rid of the c in c6 so i can convert it by using parse.
This is my code.
public partial class MainWindow : Window
{
static Random rndmlist = new Random();
Random rndm = new Random();
List<string> deck = new List<string>();
int score = 0;
public MainWindow()
{
InitializeComponent();
}
private void test_Click(object sender, RoutedEventArgs e)
{
//disregard this
foreach (string j in deck)
{
testbox.Text += j + ", ";
}
}
private void btnstart_Click(object sender, RoutedEventArgs e)
{
//this is where i add all the cards to the list
for (int i = 1; i <= 13;)
{
deck.Add("c" + i);
i++;
}
for (int i = 1; i <= 13; )
{
deck.Add("s" + i);
i++;
}
for (int i = 1; i <= 13; )
{
deck.Add("h" + i);
i++;
}
for (int i = 1; i <= 13; )
{
deck.Add("d" + i);
i++;
}
}
private void btnbegin_Click(object sender, RoutedEventArgs e)
{
//this is where i take a random card from the list and display it in textBox2
int r = rndmlist.Next(deck.Count);
textBox2.Text = ((string)deck[r]);
//disregard this
testbox.Text += ((string)deck[r]) + ", ";
deck.Remove((string)deck[r]);
}
private void btnhigh_Click(object sender, RoutedEventArgs e)
{
//this is where i want to compare the cards.
}
}
Thank you in advance for reading this. (:
I'd better create a class Card, which represents a card, with 2 properties: Color and Number and implemented method Card.ParseFromString()
Try this,
string SubString = MyString.Substring(1);
But take care if the string is empty, it is an error case.
Assuming there will always be one (and only one) character before the number, you can simply do this:
string numberAsString = "c2".Substring(1);
And to make that an int:
int number = Int32.Parse(numberAsString);
You can use Regex to replace all alpha characters eg
string result = Regex.Replace(myString, #"[a-zA-Z\s]+", string.Empty);
string str = "c12";
var noChars = str.SubString(1); // take a new string from index 1
var number = Int32.Parse(noChars);

Looping through Textboxes to retrieve data, c#

I have a class called "Player" with a constructor that takes 2 strings and an int.
These are declared in Textboxes on a form, with each team (Home H / Away A) having a different name, and each name type (Last L / First F) adding to the textbox's name. therefor giving a unique name such as txtFHome1.
In a foreach loop I want to create a new Player with the details of the textboxes on a page.
This is what I have got so far.
List <Player> HomeTeam = new List<Player>
private void btnAccept_Click(object sender, EventArgs e)
{
foreach (Control c in this.Controls)
{
for (int i = 0; i < 10; i++)
{
HomeTeam.Add (new Player(c.Name.EndsWith("FHome"+i),c.Name.EndsWith("LHome"+i),c.Name.EndsWith("upDownH"+i)));
}
}
}
any help?
From you post I understand that there are always 3 controls for 11 players, so there is no need to iterate trough all Controls in the form.
private void btnAccept_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
var player = new Player(((TextBox)this.Controls.FindControl("FHome" + i)).Text, ((TextBox)this.Controls.FindControl("LHome" + i)).Text, ((NumericUpDown)this.Controls.FindControl("upDownH" + i)).Value);
HomeTeam.Add(player);
}
}
The first way is to use dictionaries with all controls. It is the fastest and easiest way.
Dictionary<int, TextBox> FHome;
Dictionary<int, TextBox> LHome;
Dictionary<int, TextBox> upDownH;
You should add the controls like this:
FHome.Add(0, textBoxLHome0);
FHome.Add(1, textBoxLHome1);
Then in your code you can use
for (int i = 0; i < 10; i++)
{
HomeTeam.Add (new Player(FHome[i].Text, LHome[i].Text, upDownH[i].Text));
}
try this:
Controls.OfType<TextBox>().ToList().ForEach((textbox) =>
{
for (int i = 0; i < 10; i++)
{
textbox.Text = "your text";
}
});
remember to include using System.Linq
I advice you to at lease try an encapsulate the three textboxes into a single UserControl like so:
public partial class ControlPlayerParams : UserControl {
public string Param1 { get { return this.textBox1.Text; } }
public string Param2 { get { return this.textBox2.Text; } }
public string Param3 { get { return this.textBox3.Text; } }
public ControlPlayerParams() {
this.InitializeComponent();
}
}
That way, you could at least do what you wanted to do more fluently and more safely (plus you get to modify just one UserControl in case you need something changed (Validation ??)):
foreach (ControlPlayerParams cpp in this.Controls.OfType<ControlPlayerParams>())
HomeTeam.Add(new Player(cpp.Param1, cpp.Param2, cpp.Param3));
BUT you should rethink the architecture of the app a bit if you ask me.

Categories

Resources