VS WPF Program keeps crashing when checking if statement - c#

i just finished making an WPF program by Visual Studio 2012 about a simple Students Grading System.
all goes fine and it shows no error or invalid statements (red lines)
and there is a submit button, but whenever i press it a second time, the program crashes.
i checked my code several times and i can't find a solution. so it might be bother :S
the program works such as this:
the user have to enter a number of students to put grades. --> press OK, list of fields appear, when the user done inputting grades --> press submit. the values are all entered to 2 arrays, one for names and the other for grades which will be converted to letters.
the fields will be cleared for the second students, and so on until the number of students reached. the program should give a messagebox with containing the names and their Letter-grades.
using System.IO;
namespace Grading_System_Project_3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public static int nbofstudents;
public double m1, m2, p1, p2, f;
public int i = 0;
public int l;
public double avg;
public string name;
public char fg;
public char[] gr;
public string[] names;
public MainWindow()
{
InitializeComponent();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
if (Convert.ToInt32(textBox1.Text) <= 0)
{
MessageBox.Show("Please Enter a valid students number");
}
else
{
nbofstudents = Convert.ToInt32(textBox1.Text);
StreamWriter SW = File.CreateText(#"C:\grades.txt");
SW.Close();
textBox2.Visibility = System.Windows.Visibility.Visible;
textBox3.Visibility = System.Windows.Visibility.Visible;
textBox4.Visibility = System.Windows.Visibility.Visible;
textBox5.Visibility = System.Windows.Visibility.Visible;
textBox6.Visibility = System.Windows.Visibility.Visible;
textBox7.Visibility = System.Windows.Visibility.Visible;
label2.Visibility = System.Windows.Visibility.Visible;
label3.Visibility = System.Windows.Visibility.Visible;
label4.Visibility = System.Windows.Visibility.Visible;
label5.Visibility = System.Windows.Visibility.Visible;
label6.Visibility = System.Windows.Visibility.Visible;
label7.Visibility = System.Windows.Visibility.Visible;
}
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
StreamWriter sw2 = new StreamWriter(#"C:\grades.txt");
if (i < nbofstudents)
{
name = textBox2.Text;
m1 = Convert.ToInt32(textBox3.Text);
m2 = Convert.ToInt32(textBox4.Text);
p1 = Convert.ToInt32(textBox5.Text);
p2 = Convert.ToInt32(textBox6.Text);
f = Convert.ToInt32(textBox7.Text);
avg = (m1 + m2 + p1 + p2 + f) / 5;
if (avg >= 0 && avg <= 59)
{
fg = 'F';
}
else if (avg >= 60 && avg <= 69)
{
fg = 'D';
}
else if (avg >= 70 && avg <= 79)
{
fg = 'C';
}
else if (avg >= 80 && avg <= 89)
{
fg = 'B';
}
else if (avg >= 90 && avg <= 100)
{
fg = 'A';
}
string temp = Convert.ToString(fg);
try
{
sw2.WriteLine(name + "\t" + temp);
sw2.WriteLine();
sw2.Close();
}
catch (IOException ex)
{
MessageBox.Show(ex.Message);
}
i++;
textBox2.Clear();
textBox3.Clear();
textBox4.Clear();
textBox5.Clear();
textBox6.Clear();
textBox7.Clear();
}
else
{
try
{
StreamReader rf = new StreamReader(#"C:\grades.txt");
string s = "";
while ((s = rf.ReadLine()) != null)
{
MessageBox.Show(rf.ReadLine());
}
rf.Close();
}
catch (IOException ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
}

Related

odd text display C#

I have the following code in a windows form:
for (int i = 1; (i <= 10); i++)
{
if ((worker.CancellationPending == true))
{
e.Cancel = true;
break;
}
else
{
try
{
string message = "";
string m = "";
textBox2.Text = "";
int count = 0;
while (TestConnection(client))
{
char tt = ' ';
try
{
tt = Convert.ToChar(sr.Read());
if (count < 4)
{
message = tt.ToString();
m += message;
count += 1;
}
else if (count >= 4)
{
this.Invoke(new BindTextBoxControl(UpdateTextbox), new object[] {m + "\r\n"});
textBox2.Text = m + "\r\n";
m = "";
count = 0;
}
}
catch (OverflowException)
{
m += "";
}
}
}
catch (Exception g)
{
string error = "An error occurred: '{0}'" + g;
}
this gets a continuous stream of data from a StreamReader and then displays the data (4 character string). It is supposed to replace the current string shown with a new one(if the string is rrrr and then i receive tttt it shows tttt) but what it does is remove the first letter of the current string and add the next revived letter (have rrrr get tttt shows rrrt then rrtt and so forth).
how do i get this to work properly?
EDIT:
private void UpdateTextbox(string _Text)
{
textBox1.Text = _Text;
}
delegate void BindTextBoxControl(string text);
Nothing special about these.

Array doesn't display in the message box - C#

I'm trying to display 5 scores in an array, but unfortunately all I get in the message box for the results is 0.
Any help would be appreciated.
public partial class Form1 : Form
{
private int[] scoresArray = new int[5];
private int scoreTotal = 0;
private int scoreCount = 0;
public Form1()
{
InitializeComponent();
}
when the add button is clicked the scores are stored in the array up to 5 times.
private void btnAdd_Click(object sender, EventArgs e)
{
try
{
if (txtScore.Text == "")
{
MessageBox.Show("Score is required", "Entry Error");
}
else
{
int score = Convert.ToInt32(txtScore.Text);
decimal average = 0;
if (score >= 0 && score <= 100)
{
if (scoreCount != 4)
{
scoreTotal += score;
scoresArray[scoreCount] = score;
scoreCount++;
average = scoreTotal / scoreCount;
}
else
{
MessageBox.Show("Array is full");
}
txtScoreTotal.Text = scoreTotal.ToString();
txtScoreCount.Text = (scoreCount + 1).ToString();
txtAverage.Text = average.ToString();
}
else
{
MessageBox.Show("Score must be greater than 0 and less than or equal to 100.", "Entry Error");
}
}
}
catch (FormatException)
{
MessageBox.Show("Please enter a valid number for the Score field.", "Entry Error");
}
txtScore.Focus();
}
private void btnDisplayScores_Click(object sender, EventArgs e)
{
string message = "";
for (int i = 0; i < scoresArray.Length; i++)
{
message = scoresArray[i].ToString() + "\n";
}
MessageBox.Show(message, "Scores");
}
You keep overwriting message in this loop:
for (int i = 0; i < scoresArray.Length; i++)
{
message = scoresArray[i].ToString() + "\n";
}
So it's only ever going to show the last value. You probably want to append to it instead:
for (int i = 0; i < scoresArray.Length; i++)
{
message += scoresArray[i].ToString() + "\n";
}

Trying to get a windows forms button to show the next 3 numbers in a text file

As question indicates this is what I am trying to do can anyone see how been fiddling with it for a while. Currently it only shows the first 3 numbers in the text file, when I press the nextButton I want it to go to the next 3 but it does not seem to be working..
namespace GPSProject
{
public partial class Form1 : Form
{
private int count;
internal dataPoints myDataPoints;
public Form1()
{
myDataPoints = new dataPoints();
InitializeComponent();
}
private void buttonNext_Click(object sender, EventArgs e)
{
{
Button b = (Button)sender;
if (b.Name.Equals("buttonNext"))
{
count++;
if (count == (myDataPoints.Count))
count = 0;
}
else
{
count--;
if (count < 0)
count = myDataPoints.Count - 1;
}
dataPoint a = myDataPoints.getItem(count);
textBoxLatitude.Text = a.CurLatitude;
textBoxLongtitude.Text = a.CurLongtitude;
textBoxElevation.Text = a.CurElevation;
}
}
}
}
Above is my forms window and below is my dataPoints
namespace GPSProject
{
class dataPoints
{
public int Count { get { return Points.Count; } }
List<dataPoint> Points;
//string p;
public dataPoints(/*string path*/)
{
Points = new List<dataPoint>();
// p = path;
TextReader tr = new StreamReader(/*p*/"C:/Test.txt");
string input;
while ((input = tr.ReadLine()) != null)
{
string[] bits = input.Split(',');
dataPoint a = new dataPoint(bits[0], bits[1], bits[2]);
Points.Add(a);
}
tr.Close();
}
internal dataPoint getItem(int p)
{
if (p < Points.Count)
{
return Points[p];
}
else
return null;
}
}
}
You'll need to update your while loop to take your data items 3 at a time, something like this:
while ((input = tr.ReadLine()) != null)
{
string[] bits = input.Split(',');
for (int i = 0; i < bits.Length / 3; i++)
{
dataPoint a = new dataPoint(bits[3*i], bits[3*i+1], bits[3*i+2]);
Points.Add(a);
}
}
string input = "1,2,3,4,5,6,7,8,9,10,11,12";
//string input = File.ReadAllText(/*p*/"C:/Test.txt");
List<List<string>> all = input.Split(',')
.Select((s, i) => new { s, i })
.GroupBy(x => x.i / 3)
.Select(g => g.Select(x=>x.s).ToList())
.ToList();
foreach(var bits in all)
{
Console.WriteLine("{0} {1} {2}", bits[0], bits[1], bits[2]);
//dataPoint a = new dataPoint(bits[0], bits[1], bits[2]);
//Points.Add(a);
}
This would give an output
1 2 3
4 5 6
7 8 9
10 11 12

How to by pass the "Access to path 'F:/System File Volume' is denied" exception?

I've got an application that reads all the files and sub folders within the built assembly directory and display it using a datagridview. But I when try to run the application in my network drive to try scanning the files within that drive, it gives out the exception "Access to path 'F:/System File Volume' is denied" and then the application will stop running. Any idea on how to get pass the System File Volume, and still display those files which can be access. Here is my code if needed :
private void Form1_Load(object sender, EventArgs e)
{
count = 0;
timer = new Timer();
timer.Interval = 1000;
timer.Tick += new EventHandler(timer1_Tick);
timer.Start();
//FileIOPermission permit;
try
{
s1 = Directory.GetFiles(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "*.*", SearchOption.AllDirectories);
//permit = new FileIOPermission(FileIOPermissionAccess.AllAccess, s1);
//permit.AddPathList(FileIOPermissionAccess.AllAccess, s1);
for (int i = 0; i <= s1.Length - 1; i++)
{
if (i == 0)
{
dt.Columns.Add("File_Name");
dt.Columns.Add("File_Type");
dt.Columns.Add("File_Size");
dt.Columns.Add("Create_Date");
}
FileInfo info = new FileInfo(s1[i]);
FileSystemInfo sysInfo = new FileInfo(s1[i]);
dr = dt.NewRow();
dr["File_Name"] = sysInfo.Name;
dr["File_Type"] = sysInfo.Extension;
dr["File_Size"] = (info.Length / 1024).ToString();
dr["Create_Date"] = sysInfo.CreationTime.Date.ToString("dd/MM/yyyy");
dt.Rows.Add(dr);
if ((info.Length / 1024) > 1500000)
{
MessageBox.Show("" + sysInfo.Name + " had reach its size limit.");
}
}
if (dt.Rows.Count > 0)
{
dataGridView1.DataSource = dt;
}
}
catch (UnauthorizedAccessException ex)
{
MessageBox.Show("Error : " + ex.Message);
throw;
}
}
private bool IsIgnorable(string dir)
{
if (dir.EndsWith(":System Volume Information")) return true;
if (dir.Contains(":$RECYCLE.BIN")) return true;
return false;
}
private void timer1_Tick(object sender, EventArgs e)
{
count++;
if (count == 60)
{
count = 0;
timer.Stop();
Application.Restart();
}
}
public string secondsToTime(int seconds)
{
int minutes = 0;
int hours = 0;
while (seconds >= 60)
{
minutes += 1;
seconds -= 60;
}
while (minutes >= 60)
{
hours += 1;
minutes -= 60;
}
string strHours = hours.ToString();
string strMinutes = minutes.ToString();
string strSeconds = seconds.ToString();
if (strHours.Length < 2)
strHours = "0" + strHours;
if (strMinutes.Length < 2)
strMinutes = "0" + strMinutes;
if (strSeconds.Length < 2)
strSeconds = "0" + strSeconds;
return strHours + ":" + strMinutes + ":" + strSeconds;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
BindingSource bind = new BindingSource();
bind.DataSource = dt;
bind.Filter = string.Format("File_Name like '%{0}%'", textBox1.Text.Trim());
}
You will have to create a try/catch block inside of your for loop and deal with the error for each file on its own, then you can continue the loop afterwards.
I would suggest making a function out of it, Here is some "air code", untested, probably syntactic wrong, but I think you get the idea:
bool GetFileInformation(File f, out string name)
{
name=null;
try
{
FileInfo info = new FileInfo(f);
FileSystemInfo sysInfo = new FileSystemInfo(f);
name=sysInfo.Name;
}
catch(Exception ex)
{
return false;
}
return true;
}
Now you can easily build the loop around this:
for (int i = 0; i <= s1.Length - 1; i++)
{
if (GetFileInformation(s1[i], out name)
{
dr = dt.NewRow();
dr["File_Name"] = name;
// ....
}
}

Displaying random numbers in C#

I'm trying to design a code where one guess a number. I defined the range which number to display in my listbox. I started to write Random(1,10) but if I enter 11, it still writes in my listbox. How can I just write the number selected from my range, which is 1-10?
Here is a part of my code:
private void btnOk_Click(object sender, EventArgs e)
{
string yourNumber;
yourNumber = textBox1.Text.Trim();
int returnNumber = RandomNumber(1, 10);
int.TryParse(textBox1.Text, out returnNumber);
listBox1.Items.Add(returnNumber);
}
Additional question
If I would like to display a range of number like for example 1-10, how could I do the following? The user will type 11 the program will not accept that.
I made something like this:
int returnNumber = RandomNumber(1, 10);
string yourNumber;
yourNumber = textBox1.Text.Trim();
if(Int32.TryParse(textBox1.Text>=1)) && (Int32.TryParse(textBox1.Text<=10));
{
listBox1.Items.Add(yourNumber);
textBox1.Text = string.Empty;
}
Something is wrong in the program.
Update
For Nathaniel, I tried this one:
int returnNumber=RandomNumber(1,10);
int counter=1;
int yourNumber;
Int32.TryParse(textBox1.Text.Trim(), out yourNumber);
if (yourNumber >=1 && yourNumber <= 10)
{
listBox1.Items.Add(yourNumber);
}
else
{
MessageBox.Show("Please enter a number between 1-10");
}
What I would like to do is design a program for guessing a number. So this is the first part.
Update
Here is my final code, can it be improved? I think the next thing I'll do is to limit the times the user types the input. That means, they can only guess the right number 3 times or 5 times. Not sure where to implement it
namespace Guessing_Game
{
public partial class Form1 : Form
{
private static int randomNumber;
private const int rangeNumberMin = 1;
private const int rangeNumberMax = 10;
public Form1()
{
InitializeComponent();
randomNumber = GenerateNumber(rangeNumberMin, rangeNumberMax);
}
private int GenerateNumber(int min,int max)
{
Random random = new Random();
return random.Next(min, max);
}
private void btnOk_Click(object sender, EventArgs e)
{
int yourNumber = 0;
Int32.TryParse(textBox1.Text.Trim(), out yourNumber);
if (yourNumber>= rangeNumberMin && yourNumber<=rangeNumberMax)
{
listBox1.Items.Add(yourNumber);
if (yourNumber > randomNumber)
{
listBox2.Items.Add("No the Magic Number is lower than your number");
}
if (yourNumber < randomNumber)
{
listBox2.Items.Add("No, the Magic Number is higher than your number");
}
if(yourNumber==randomNumber)
{
listBox2.Items.Add("You guessed the Magic Number!");
btnRestart.Enabled = true;
}
}
else
{
MessageBox.Show("Please enter a number between " + rangeNumberMin + " to " + rangeNumberMax);
}
}
private void btnRestart_Click(object sender, EventArgs e)
{
listBox2.Items.Clear();
listBox1.Items.Clear();
textBox1.Text = null;
randomNumber = GenerateNumber(rangeNumberMin, rangeNumberMax);
btnRestart.Enabled = false;
}
}
The line:
int returnNunmber = RandomNumber(1, 10);
does nothing, because in the next line returnNumber is used as an output variable and will be whatever number is in textBox1. Remove the
int.TryParse(textBox1.Text, out returnNumber);
line and it will add a random number from 1 to 10 to your listbox.
EDIT::::
To answer you additional question, try:
private void btnOk_Click(object sender, EventArgs e)
{
string yourNumber;
yourNumber = textBox1.Text.Trim();
int returnNumber;
int.TryParse(textBox1.Text, out returnNumber);
if( returnNumber < 1 || returnNumber > 10) {
returnNumber = RandomNumber(1, 10);
}
listBox1.Items.Add(returnNumber);
}
Some minor changes to your code, condensing a couple lines and adding the limit code, utilizing the list of guesses as the counter:
namespace Guessing_Game
{
public partial class Form1 : Form
{
private static int randomNumber;
private const int rangeNumberMin = 1;
private const int rangeNumberMax = 10;
private const int maxGuesses = 5;
public Form1()
{
InitializeComponent();
randomNumber = GenerateNumber(rangeNumberMin, rangeNumberMax);
}
private int GenerateNumber(int min,int max)
{
Random random = new Random();
return random.Next(min, max);
}
private void btnOk_Click(object sender, EventArgs e)
{
int yourNumber = 0;
if (Int32.TryParse(textBox1.Text.Trim(), out yourNumber) &&
yourNumber>= rangeNumberMin && yourNumber<=rangeNumberMax)
{
listBox1.Items.Add(yourNumber);
if (yourNumber > randomNumber)
{
listBox2.Items.Add("No the Magic Number is lower than your number");
}
else if (yourNumber < randomNumber)
{
listBox2.Items.Add("No, the Magic Number is higher than your number");
}
else
{
listBox2.Items.Add("You guessed the Magic Number!");
textBox1.Enabled = false;
btnOk.Enable = false;
btnRestart.Enabled = true;
}
//Will stop on the 5th guess, but guards the case that there were more than 5 guesses
if(listBox1.Items.Count >= maxGuesses && yourNumber != randomNumber)
{
listBox2.Items.Add("You are out of guesses!");
textBox1.Enabled = false;
btnOk.Enable = false;
btnRestart.Enabled = true;
}
}
else
{
MessageBox.Show("Please enter a number between " + rangeNumberMin + " to " + rangeNumberMax);
}
}
private void btnRestart_Click(object sender, EventArgs e)
{
listBox2.Items.Clear();
listBox1.Items.Clear();
textBox1.Text = null;
randomNumber = GenerateNumber(rangeNumberMin, rangeNumberMax);
btnRestart.Enabled = false;
textBox1.Enabled = true;
btnOk.Enable = true;
}
}
}
Editted to prevent the "You're out of guesses" message when the number is correctly guessed on the last guess.
Lets take that piece by piece:
int returnNumber = RandomNumber(1, 10);
There is no inbuilt RandomNumber function; note that with the Random class, the end value is exclusive, so for a number in a range, you'll need something like:
static readonly Random rand = new Random();
static int Random(int min, int max) {
if(max < min) throw new ArgumentOutOfRangeException("max");
lock(rand) {
return rand.Next(min, max + 1);
}
}
However, you then throw away this value completely:
int.TryParse(textBox1.Text, out returnNumber);
The use of out means that the previous value of returnNumber is ignored completely. I'm not sure what your intent is, but it seems like you just want to check the value:
if(int.TryParse(textBox1.Text, out returnNumber)
&& returnNumber >= 1 && returnNumber <= 10)
{
listBox1.Items.Add(returnNumber);
}
I've tried to look at the last example, but it really isn't clear what you are trying to do - can you clarify?
(edited after question edit and comments)
You would need a counter, which you increment for failed tries - something like:
using System;
using System.Drawing;
using System.Windows.Forms;
class MyForm : Form {
Button btn;
ListBox lst;
TextBox tb;
const int MaxTries = 3, MaxNumber = 10;
int targetNumber, guessCount = 0;
public MyForm() {
targetNumber = new Random().Next(1, MaxNumber + 1);
Text = "Guess a number";
Icon = SystemIcons.Question;
Controls.Add(lst = new ListBox {Dock=DockStyle.Fill});
Controls.Add(btn = new Button {Text="Guess",Dock=DockStyle.Top});
Controls.Add(tb = new TextBox {Dock=DockStyle.Top});
btn.Click += btn_Click;
}
void btn_Click(object sender, EventArgs e) {
int userNumber;
if (int.TryParse(tb.Text.Trim(), out userNumber)) {
if (userNumber < 1 || userNumber > MaxNumber) {
lst.Items.Add("Did I mention... between 1 and " + MaxNumber);
} else {
if (userNumber == targetNumber) {
lst.Items.Add("Well done! You guessed well");
btn.Enabled = false; // all done
} else {
lst.Items.Add(targetNumber < userNumber
? "Try a bit lower" : #"It is bigger than that");
if (++guessCount >= MaxTries) {
btn.Enabled = false;
lst.Items.Add("Oops, should have picked more wisely");
}
}
}
} else {
lst.Items.Add("Nice; now give me a number");
}
}
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MyForm());
}
}

Categories