I'm new to windows forms.
My program is to show random questions for the user to answer and I want when the user press the end button to show the questions and the user answers and the right answer should my question and answers be in var?
I created a string list and can't seem to figure it out.
namespace WindowsFormsApplication7
{
public partial class Form1 : Form
{
int numofquestionleft;
int answer;
int useranswer33;
Timer Clock = new Timer();
List<string> questions = new List<string>();
List<string> answers = new List<string>();
List<string> useranswers= new List<string>();
public Form1(){
}
int[] Rand(int v)
{//random number generater
Random r = new Random();
int a = r.Next(1,v);
int b = r.Next(1,v);
int[] N = {Math.Max(a,b) , Math.Min(a,b)};
return N;
}
void generate()
{
//user choosing the range of numbers that is used in questions
int range = 0;
switch (rangebox1.SelectedIndex)
{
case 0:
range = 100;
break;
case 1:
range = 500;
break;
case 2:
range = 1000;
break;
default:
MessageBox.Show("Put a range !");
break;
}
int[] numbers = Rand(range);
switch (Operationbox1.SelectedIndex)
{
case 0:
questionlbl1.Text = string.Format("{0} + {1} =",numbers[0],numbers[1]);
answer = numbers[0] + numbers[1];
answers.Add(answer.ToString());
break;
case 1:
questionlbl1.Text = string.Format("{0} - {1} =" , numbers[0], numbers[1]);
answer = numbers[0] - numbers[1];
answers.Add(answer.ToString());
break;
case 2:
questionlbl1.Text = string.Format("{0} * {1} =" , numbers[0], numbers[1]);
answer = numbers[0] * numbers[1];
answers.Add(answer.ToString());
break;
case 3:
questionlbl1.Text = string.Format("{0} / {1} =" , numbers[0], numbers[1]);
answer = numbers[0] / numbers[1];
answers.Add(answer.ToString());
break;
default:
MessageBox.Show("Please insert a operation");
break;
}
\
}
void numberquest()
{//if the number of question left is more than 0 genrate and minues 1 question
if (numofquestionleft > 0)
{
generate();
}
else
{
MessageBox.Show("End of questions, Please press END");
}
numofquestionleft--;
numberofquestionnumber.Text = "Questions left " + numofquestionleft;
}
private void genbutton1_Click(object sender, EventArgs e)
{ //Button that start the timer and generate the question
numofquestionleft = Convert.ToInt32(numofquest1.Text);
generate();
}
private void end22_Click(object sender, EventArgs e)
{
foreach (var questionlist in question)
{
// here is my problem what should I put here to display the question list
}
}
private void button2_Click(object sender, EventArgs e)
{//button that checks if the useranswer is right or wrong
useranswer33 = Convert.ToInt32(useranswerbox1.Text);
useranswers.Add(answer.ToString());
if (useranswer33 == answer)
{
result.Text = "Your answer is correct";
}
else
{
result.Text = "Your answer is Wrong, The correct answer;
}
}
}
}
You can do such thing to dynamically generate controls to create your quiz:
var questions = new string[]
{
"This is the question 1",
"This is the question 2",
"This is the question 3",
"This is the question 4"
}
int x = 50;
int y = 10;
int dy = 30;
int width = 250;
foreach ( var question in questions )
{
var textbox = new TextBox();
textbox.Text = question;
textbox.Width = width;
textbox.Location = new Point(x, y);
Controls.Add(textbox);
y += dy;
}
You can adapt for what you want by changing and adding controls for you need: type of controls, appearance, locations, sizes, content, and so on.
Here controls are added to the form itself but you can put them in a panel or any container:
SomePanel.Controls.Add(textbox);
Hence you can create questions with labels and add a textbox or radioboxes for answers and name them. You can also keep controls created to get answers later:
var texboxesAnswers = new List<TextBox>()
int index = 0;
// ...
foreach ( var question in questions )
{
var label = new Label();
label.Text = question;
label.AutoSize = true;
label.Location = new Point(x, y);
PanelQuestions.Controls.Add(label);
y += dy;
var textbox = new TextBox();
textbox.Text = "";
textbox.Width = width;
textbox.Location = new Point(x, y);
textbox.Name = "TextBoxAnswer" + (index++);
PanelQuestions.Controls.Add(textbox);
texboxesAnswers.Add(textbox);
y += dy + dy / 2;
}
Without using textboxesAnswers you can get all answers like that:
using System.Linq;
var textboxesAnswers = PanelQuestions.Controls
.OfType<TextBox>()
.Where(n => n.Name.StartsWith("TextBoxAnswer"));
guys I just want some help. Sorry, I'm a newbie in C# programming. And my problem is that when I enter a value let say I enter 2, I want to print out: (Inserted so far: 0 out of 23.) But what happens is it shows the same value of soda which is 30 instead of 23.
namespace VendingMachine
{
class Program
{
static void Main(string[] args)
{
int itemPrice = 0;
int moneyAvailable = 0;
int change = 0;
int soda = 30;
int juice = 23;
int water = 15;
string userChoice;
// Menu
Console.WriteLine();
Console.WriteLine("1. Soda = P30");
Console.WriteLine("2. Juice = P23");
Console.WriteLine("3. Water = P15");
Console.WriteLine("4. Exit");
Console.WriteLine();
// Values entered by the user
Console.Write("Your choice: ");
userChoice = Console.ReadLine();
Console.WriteLine("================================");
// THE MAIN PROBLEM
if (itemPrice < soda)
{
Console.WriteLine($"Inserted so far: P0 out of P{soda}");
}
Console.Write("Enter the amount of Money!: P");
moneyAvailable = int.Parse(Console.ReadLine());
switch (userChoice)
{
case "1":
itemPrice = itemPrice + soda;
break;
case "2":
itemPrice = itemPrice + juice;
break;
case "3":
itemPrice = itemPrice + water;
break;
default:
Console.WriteLine("Invalid. Choose 1, 2 or 3.");
break;
}
You are using string interpolation with wrong variable name
if (itemPrice < soda)
{
Console.WriteLine($"Inserted so far: P0 out of P{itemPrice}");
// ^^^^^^^^^^ Problem is here
}
Instead of printing value of soda everytime you should print value of itemPrice.
This print statement with if condition should goes to end of switch statement
Something like,
Console.Write("Enter the amount of Money!: P");
moneyAvailable = int.Parse(Console.ReadLine());
switch (userChoice)
{
case "1":
itemPrice = itemPrice + soda;
break;
case "2":
itemPrice = itemPrice + juice;
break;
case "3":
itemPrice = itemPrice + water;
break;
default:
Console.WriteLine("Invalid. Choose 1, 2 or 3.");
break;
}
if (itemPrice < soda)
{
Console.WriteLine($"Inserted so far: P0 out of P{itemPrice}");
}
Wrong variable in the string output: {soda} instead of {itemPrice}
In your case, you have to check if (itemPrice < soda) after switch (userChoice)
This is what you wanted to do:
class Program
{
static void Main(string[] args)
{
List<Item> items = new List<Item>()
{
new Item
{
Name = "Soda",
Price = 30
},
new Item
{
Name = "Juice",
Price = 23
},
new Item
{
Name = "Water",
Price = 15
}
};
while (true)
{
//MENU
Log("Available Items:");
for(int i = 0; i < items.Count; i++)
{
Log("{0}. {1} = P{2}", i, items[i].Name, items[i].Price);
}
Console.WriteLine();
bool isInputValid = false;
string userChoice = string.Empty;
int chosenIndex = 0;
while (isInputValid == false)
{
try
{
Log("Choose your Item:");
userChoice = Console.ReadLine();
chosenIndex = int.Parse(userChoice);
if(chosenIndex < 0 || chosenIndex >= items.Count)
{
throw new ArgumentOutOfRangeException();
}
isInputValid = true;
}
catch
{
Log("Invalid choice!");
}
}
Item chosenItem = items[chosenIndex];
bool isPriceReached = false;
string userInsertedMoney = string.Empty;
int insertedMoney = 0;
while (isPriceReached == false)
{
try
{
Log("P{0} of P{1} needed Money for {2} inserted, waiting for more...", insertedMoney, chosenItem.Price, chosenItem.Name);
userInsertedMoney = Console.ReadLine();
insertedMoney += int.Parse(userInsertedMoney);
isPriceReached = insertedMoney >= chosenItem.Price;
}
catch
{
Log("Invalid money!");
}
}
Log("Here is your {0} with a rest of {1} money.{2}", chosenItem.Name, insertedMoney - chosenItem.Price, Environment.NewLine);
}
}
private static void Log(string message, params object[] args)
{
Console.WriteLine(string.Format(message, args));
}
}
public class Item
{
public string Name { get; set; }
public int Price { get; set; }
}
I was wondering how I would make a picture box become invisible or visible when a certain integer matches.
My program revolves around 2 players going around a board, and when they add there 2 Di up, they will move the amount of spaces.
My problem being, My friend and I have no idea what is wrong with the current code we have, it throws no errors which baffles him, especially myself.
I've made it so my program add's the Di up on every roll, and add's it to the integer.
Anyone have any idea's on whats wrong? If not, a better approach?
Code
private void SelectPos(PictureBox pic)
{
PictureBox[] numbers = { P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31, P1_32, P1_33, P1_34, P1_35, P1_36, P1_37, P1_38, P1_39, P1_40, P1_41, P1_42, P1_43, P1_44, P1_45, P1_46, P1_47, P1_48, P1_49 };
for (int i = 0; i < numbers.Length; i++)
{
if (pic == numbers[i])
{
numbers[i].Visible = true;
MessageBox.Show("k");
}
{
numbers[i].Visible = false;
MessageBox.Show("l");
}
}
}
private void bunifuFlatButton1_Click(object sender, EventArgs e)
{
Roll();
System.Threading.Thread.Sleep(100);
Roll2();
Goes_Num.Text = (int.Parse(Goes_Num.Text) + 1).ToString();
if (Convert.ToInt32(Goes_Num.Text) % 2 == 0)
{
WhichPlayer.Text = "Player 2";
P2_Number.Text = (int.Parse(P2_Number.Text) + 1).ToString();
int p2Int = Convert.ToInt32(P2_Pos.Text);
P2_Pos.Text = (p2Int + dice + dice2).ToString();
}
else if (Convert.ToInt32(Goes_Num.Text) % 2 != 0)
{
WhichPlayer.Text = "Player 1";
P1_Number.Text = (int.Parse(P1_Number.Text) + 1).ToString();
int p1Int = Convert.ToInt32(P1_Pos.Text);
P1_Pos.Text = (p1Int + dice + dice2).ToString();
int P1 = (Convert.ToInt32(P1_Pos.Text));
SelectPos(P1_1);
/*switch (P1)
{
case 1:
P1_1.Visible = true;
break;
case 2:
P1_2.Visible = true;
break;
}*/
/*String[] hi = { "1", "2" };
for (int i = 0; i < hi.Length; i++)
{
var visible = p1
if(visible == hi[i])
{
hi[i].Visible = true;
}
else
{
hi[i].Visible = false;
}
}*/
}
}
(P1-1 all the way to P1-49 are images)
Thanks,
James
It looks like you're trying to pass an int to your SelectPos function but it expects a PictureBox. You could fix this doing something similar to the following:
private void SelectPos(int pic)
{
PictureBox[] numbers = { P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31, P1_32, P1_33, P1_34, P1_35, P1_36, P1_37, P1_38, P1_39, P1_40, P1_41, P1_42, P1_43, P1_44, P1_45, P1_46, P1_47, P1_48, P1_49 };
//Set all picture boxes to be not visible
for (int i = 0; i < numbers.Length; i++)
{
numbers[i].Visible = false;
}
//Set the picture at the given index to visible
numbers[pic].Visible = true;
}
private void bunifuFlatButton1_Click(object sender, EventArgs e)
{
Roll();
System.Threading.Thread.Sleep(100);
Roll2();
Goes_Num.Text = (int.Parse(Goes_Num.Text) + 1).ToString();
if (Convert.ToInt32(Goes_Num.Text) % 2 == 0)
{
WhichPlayer.Text = "Player 2";
P2_Number.Text = (int.Parse(P2_Number.Text) + 1).ToString();
int p2Int = Convert.ToInt32(P2_Pos.Text);
P2_Pos.Text = (p2Int + dice + dice2).ToString();
}
else if (Convert.ToInt32(Goes_Num.Text) % 2 != 0)
{
WhichPlayer.Text = "Player 1";
P1_Number.Text = (int.Parse(P1_Number.Text) + 1).ToString();
int p1Int = Convert.ToInt32(P1_Pos.Text);
P1_Pos.Text = (p1Int + dice + dice2).ToString();
int P1 = (Convert.ToInt32(P1_Pos.Text));
SelectPos(P1);
}
}
You may have to manipulate the value of pic so that it is within the bounds of the array (0-48). For example if pic is between 1 and 49 you would need to subtract 1: numbers[pic-1]. Without seeing your whole program I can't tell you exactly how that part of the code would look but it should be pretty easy to figure out. If you aren't familiar with arrays and indexing check out this link or just Google C# Arrays.
As a side note it would be better to the numbers array as a private member of the class this code is in. Unless the values in the array change there's no point in building the array every time the method is called.
Complete code:
private void SelectPos(int pic)
{
PictureBox[] numbers = { P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P1_10, P1_11, P1_12, P1_13, P1_14, P1_15, P1_16, P1_17, P1_18, P1_19, P1_20, P1_21, P1_22, P1_23, P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31, P1_32, P1_33, P1_34, P1_35, P1_36, P1_37, P1_38, P1_39, P1_40, P1_41, P1_42, P1_43, P1_44, P1_45, P1_46, P1_47, P1_48, P1_49 };
//Set all picture boxes to be not visible
for (int i = 0; i < numbers.Length; i++)
{
numbers[i].Visible = false;
}
//Set the picture at the given index to visible
numbers[pic].Visible = true;
}
private void SelectPos2(int pic2)
{
PictureBox[] numbers2 = { P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P2_10, P2_11, P2_12, P2_13, P2_14, P2_15, P2_16, P2_17, P2_18, P2_19, P2_20, P2_21, P2_22, P2_23, P2_24, P2_25, P2_26, P2_27, P2_28, P2_29, P2_30, P2_31, P2_32, P2_33, P2_34, P2_35, P2_36, P2_37, P2_38, P2_39, P2_40, P2_41, P2_42, P2_43, P2_44, P2_45, P2_46, P2_47, P2_48, P2_49 };
//Set all picture boxes to be not visible
for (int i = 0; i < numbers2.Length; i++)
{
numbers2[i].Visible = false;
}
//Set the picture at the given index to visible
numbers2[pic2].Visible = true;
}
private void bunifuFlatButton1_Click(object sender, EventArgs e)
{
Roll();
System.Threading.Thread.Sleep(100);
Roll2();
Goes_Num.Text = (int.Parse(Goes_Num.Text) + 1).ToString();
if (Convert.ToInt32(Goes_Num.Text) % 2 == 0)
{
WhichPlayer.Text = "Player 2";
P2_Number.Text = (int.Parse(P2_Number.Text) + 1).ToString();
int p2Int = Convert.ToInt32(P2_Pos.Text);
P2_Pos.Text = (p2Int + dice + dice2).ToString();
int P2 = (Convert.ToInt32(P2_Pos.Text));
SelectPos2(P2);
}
else if (Convert.ToInt32(Goes_Num.Text) % 2 != 0)
{
WhichPlayer.Text = "Player 1";
P1_Number.Text = (int.Parse(P1_Number.Text) + 1).ToString();
int p1Int = Convert.ToInt32(P1_Pos.Text);
P1_Pos.Text = (p1Int + dice + dice2).ToString();
int P1 = (Convert.ToInt32(P1_Pos.Text));
SelectPos(P1);
}
}
I would like to display four images at the same time and upon form load the images switch places. Currently, images will appear in different numbers, for example: 1 image will appear or 2 images, etc up 4. I also want to ensure that no duplicates will appear.
Code from Form1_Load:
PictureBox[] boxes = new PictureBox[4];
boxes[0] = pictureBox0;
boxes[1] = pictureBox1;
boxes[2] = pictureBox2;
boxes[3] = pictureBox3;
for (int i = 0; i < boxes.Length; i++)
{
int switcher = r.Next(0, 5);
switch (switcher)
{
case 0:
{ boxes[i].Image = Properties.Resources.dog0; } break;
case 1:
{ boxes[i].Image = Properties.Resources.dog1; } break;
case 2:
{ boxes[i].Image = Properties.Resources.dog2; } break;
case 3:
{ boxes[i].Image = Properties.Resources.dog3; } break;
}
}
Two examples given above as to what currently happens.
Update - Working
The program now moves images around upon Load and there are no duplicates :)
List<Bitmap> resources = new List<Bitmap>();
resources.Add(Properties.Resources.dog0);
resources.Add(Properties.Resources.dog1);
resources.Add(Properties.Resources.dog2);
resources.Add(Properties.Resources.dog3);
resources = resources.OrderBy(a => Guid.NewGuid()).ToList();
for (int i = 0; i < resources.Count; i++)
{
pictureBox0.Image = resources[0];
pictureBox1.Image = resources[1];
pictureBox2.Image = resources[2];
pictureBox3.Image = resources[3];
}
Two example given above showing what happens now that it works.
The implementation is quite simple. Firstly, you need to shuffle the array and then iterate through it. Fisher–Yates shuffle.
Create a method ShuffleImages as below:
public void ShuffleImages(PictureBox[] img)
{
Random r = new Random();
for (int i = 0; i < img.Length - 1; i++)
{
int j = r.Next(i, img.Length);
PictureBox temp = img[j];
img[j] = img[i];
img[i] = temp;
}
}
and call the method in your Form1_Load event:
private void Form1_Load(object sender, EventArgs e)
{
PictureBox[] boxes = new PictureBox[4];
boxes[0] = pictureBox0;
boxes[1] = pictureBox1;
boxes[2] = pictureBox2;
boxes[3] = pictureBox3;
ShuffleImages(boxes); //call the method
for (int i = 0; i <= 3; i++)
{
switch (i)
{
case 0:
{ boxes[i].Image = Properties.Resources.dog0; }
break;
case 1:
{ boxes[i].Image = Properties.Resources.dog1; }
break;
case 2:
{ boxes[i].Image = Properties.Resources.dog2; }
break;
case 3:
{ boxes[i].Image = Properties.Resources.dog3; }
break;
}
}
}
As M.kazem Ahkhary points out you need to shuffle the images:
List<Bitmap> resources = new List<Bitmap>();
resources.Add(Properties.Resources.dog0);
resources.Add(Properties.Resources.dog1);
resources.Add(Properties.Resources.dog2);
resources.Add(Properties.Resources.dog3);
resources = resources.OrderBy(a => Guid.NewGuid()).ToList(); // Dirty but effective shuffle method
pictureBox0.Image = resources[0];
pictureBox1.Image = resources[1];
pictureBox2.Image = resources[2];
pictureBox3.Image = resources[3];
I'm geting a StackOverflowException. Somehow, posting here seemed appropriate.
I'm using Windows Forms in a C# application. This application is intended to run on Linux, FreeBSD and Mac-OS, so I can't use WPF, so please don't suggest it.
My guess is that I'm missing a nuance of WinForms, but I cant seem to figure out what.
The ComboBox is generated by the GUI form builder in VS 2010.
The specific lines of code that are throwing the error are here:
if(cur_num_is_valid)
{
cbx_material_num.Text = num;
}
else
{
num = "0";
//I only have one of the following two at a time. Both overflow
cbx_material_num.SelectedIndex = 0;
cbx_material_num.Text = "0";
}
Since the code is somewhat complex, here's the whole function code. 'cbx_' indicates a combo box. 'txtb_' is a text box.
private void cbx_material_numobj_SelectedIndexChanged(object sender, EventArgs e)
{
string obj = cbx_material_obj.Text;
string num = cbx_material_num.Text;
int selnum = 0;
int n = 0;
//do we need to recreate the numbers array?
bool cur_num_is_valid = false;
cbx_material_num.Items.Clear();
if(obj != lastobj)
{
n = m_demo.get_object_modifiers(obj);
for(int i = 0; i <= n; i++)
{
string s = i.ToString();
if(s == num && i < n) cur_num_is_valid = true;
cbx_material_num.Items.Add(s);
}
}
if(cur_num_is_valid)
{
cbx_material_num.Text = num;
}
else
{
num = "0";
//Overflow here:
cbx_material_num.SelectedIndex = 0;
}
try
{
selnum = int.Parse(num);
}
catch(Exception)
{
MessageBox.Show("Error, second select menu after 'object modifiers' must be a number, not '"+num+"'.");
cbx_material_num.Text="0";
return;
}
if(selnum >= n)
{
txtb_material_param1.Text = "0";
txtb_material_param2.Text = "0";
txtb_material_param3.Text = "0";
txtb_material_param4.Text = "0";
}
else
{
MaterialFace face;
MaterialParameter parameter;
int typeid;
object paramdata;
m_demo.get_object_modifiers_material(obj, selnum, out face, out parameter, out typeid, out paramdata);
cbx_material_face.Text = face.ToString();
cbx_material_paramtype.Text = parameter.ToString();
switch(typeid)
{
case 0:
txtb_material_param1.Text = ((float)paramdata).ToString();
cbx_material_datatype.Text = "float";
goto case -1;
case 1:
float[] parsf = ((float[])paramdata);
txtb_material_param1.Text = parsf[0].ToString();
txtb_material_param2.Text = parsf[1].ToString();
txtb_material_param3.Text = parsf[2].ToString();
txtb_material_param4.Text = parsf[3].ToString();
cbx_material_datatype.Text = "float[]";
break;
case 2:
txtb_material_param1.Text = ((int)paramdata).ToString();
cbx_material_datatype.Text = "int";
goto case -1;
case 3:
int[] parsi = ((int[])paramdata);
txtb_material_param1.Text = parsi[0].ToString();
txtb_material_param2.Text = parsi[1].ToString();
txtb_material_param3.Text = parsi[2].ToString();
txtb_material_param4.Text = parsi[3].ToString();
cbx_material_datatype.Text = "int[]";
break;
case -1: //can't actuall be returned, used to 'blank' the last three as '0'
txtb_material_param2.Text = "0";
txtb_material_param2.Text = "0";
txtb_material_param3.Text = "0";
break;
case 4:
OpenTK.Graphics.Color4 paramc = ((OpenTK.Graphics.Color4)paramdata);
txtb_material_param1.Text = paramc.R.ToString();
txtb_material_param2.Text = paramc.G.ToString();
txtb_material_param3.Text = paramc.B.ToString();
txtb_material_param4.Text = paramc.A.ToString();
cbx_material_datatype.Text = "Color4";
break;
default: //5
Vector4 paramv = ((Vector4)paramdata);
txtb_material_param1.Text = paramv.X.ToString();
txtb_material_param2.Text = paramv.Y.ToString();
txtb_material_param3.Text = paramv.Z.ToString();
txtb_material_param4.Text = paramv.W.ToString();
cbx_material_datatype.Text = "Vector4";
break;
}
}
}
You need to check that the SelectedIndex isn't already 0 before you try to set it:
if (cbx_material_num.SelectedIndex != 0){
cbx_material_num.SelectedIndex = 0;
}
Otherwise you're re-firing the event every time through.
I think that whenever you set this cbx_material_num.SelectedIndex = 0; within the EventHandler you invoke your
cbx_material_numobj_SelectedIndexChanged(object sender, EventArgs e)
Each call invokes another eventHandler so the stack fills up after some time.
Basically, the fact that it is called SelectedIndexChanged doesn't mean that the value has to be different from the previous one but that the value is set through its setter.