So I need to create a Yearly Summary that gives feedback from the amount of events held a year. There must be an event held each month for this to happen.
So far I have stored the months in an array like this:
public string[] sMonths = new string[12] { "01", "02", "03", "04", "05",
"06", "07", "08", "09", "10", "11", "12" };
I then initiate the array into a combo box, with a counter:
for (iCount = 0; iCount < sMonths.Length; iCount++)
{
cboMonth.Items.Add(sMonths[iCount]);
}
Then take this information from the interface (windows form) like this:
sEventName = txtEvent.Text;
sVenueName = txtVenue.Text;
lstActivity.Items.Add("Dance");
lstActivity.Items.Add("Theatre");
lstActivity.Items.Add("Music");
}
//summary
private void btnExit_Click(object sender, EventArgs e)
{
DialogResult dialogResult = MessageBox.Show("Are up you sure you want to exit?", "Exit", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (dialogResult == DialogResult.Yes)
{
Application.Exit();
}
}
private void btnAdd_Click(object sender, EventArgs e)
{
using (StreamWriter sw = new StreamWriter("EVENTS.TXT", true))
{
sw.WriteLine(txtEvent.Text);
sw.WriteLine(txtVenue.Text);
sw.WriteLine(cboMonth.SelectedItem.ToString());
sw.WriteLine(lstActivity.SelectedItem);
if (rdoRange1.Checked == true)
{
sw.WriteLine(rdoRange1.Text);
}
else if (rdoRange2.Checked == true)
{
sw.WriteLine(rdoRange2.Text);
}
else if (rdoRange3.Checked == true)
{
sw.WriteLine(rdoRange3.Text);
}
else
{
sw.WriteLine(rdoRange4.Text);
}
sw.Close();
}
}
I'm not sure if I am doing this correctly, or if I am getting my counters confused, or infact need to use more than 1? But when I then try to create the summary, nothing appears at all?
private void btnSummary_Click(object sender, EventArgs e)
{
using (StreamReader sr = new StreamReader("EVENTS.TXT"))
{
for (iCount = 12; iCount < sMonths.Length; iCount++)
{
if (iCount == 12)
{
sMonths[iCount] = sr.ReadLine();
listBox1.Items.Add("You held an event every month of the year.");
}
else
{
label1.Text = " ";
listBox1.Items.Add("You cannot produce a yearly summary until you have entered an event for each month");
}
}
I try to read the information from the file but it's returning nothing at all.
I am trying to get this to work using local variables, before transferring it into classes.
there may be many errors in my code, I am new to this.
Thanks in advance, any advice appreciated.
UPDATE:
a sample of my readfile is:
jdisfhs
ddnsojds
05
Dance
0
There will be 12 records in each of them. I need to check each value against variables and produce the outcome.
There are a few problems with this chunk:
for (iCount = 12; iCount < sMonths.Length; iCount++)
sMonths is an array of 12 elements so sMonths.Length = 12.
You create your counter with the value 12 and your condition to loop is that your counter is strictly inferior to 12, so you will never enter the loop.
To loop through an array you usually want to do something like :
for(int iCount = 0; iCount < sMonths.Length; iCount++)
But in this case you want to read a file, so your loop should be on the file reader with something like that :
private void btnSummary_Click(object sender, EventArgs e)
{
using (StreamReader sr = new StreamReader("EVENTS.TXT"))
{
string line = string.Empty;
/*the condition in the while reads the next line and puts it in line,
then tests if line is null because sr.ReadLine()
returns null when the end of the document is reached*/
while ((line = sr.ReadLine()) != null)
{
//Do your tests on line
}
}
}
Related
I am wondering why the load time for the file is so long . i would appreciate it if you would take time to look where it says
if (ReadType == 1)
Around 12,000 items loading
it takes nearly 12 seconds to load a file with a short structure i don't think this is right. I'm new to c# and could use any pointers attached below is the code and the file structure:
here also is attached a video of the issue:
video
screenshot of file:
structureloaded
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StringEditor
{
public class ItemStr
{
public int a_index;
public byte[] a_name { get; set; }
public byte[] a_descr1 { get; set; }
}
}
private void tsbOpen_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "String|*.lod";
if (ofd.ShowDialog() != DialogResult.OK)
return;
if (!ofd.FileName.Contains("strItem") && !ofd.FileName.Contains("strSkill")) //check to see if user isn't opening the right files if not return;
return;
else if (ofd.FileName.Contains("strItem"))
ReadType = 1;
else if (ofd.FileName.Contains("strSkill"))
ReadType = 2;
FileStream fs = new FileStream(ofd.FileName, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
if (ReadType == 1)
{
int max = br.ReadInt32();
int max1 = br.ReadInt32();
for (int i = 0; br.BaseStream.Position < br.BaseStream.Length; i++)
{
ItemStr itemstr = new ItemStr();
itemstr.a_index = br.ReadInt32();
itemstr.a_name = br.ReadBytes(br.ReadInt32());
itemstr.a_descr1 = br.ReadBytes(br.ReadInt32());
itemStringList.Add(itemstr);
listBox1.Items.Add(itemstr.a_index.ToString() + " - " + Encoding.GetEncoding(ISO).GetString(itemstr.a_name));
}
EnableFields();
}
fs.Close();
br.Close();
if (ReadType == 2)
{
int max = br.ReadInt32();
int max1 = br.ReadInt32();
for (int i = 0; i < max; i++)
{
skillStr skillStr = new skillStr();
skillStr.a_index = br.ReadInt32();
skillStr.a_name = br.ReadString();
skillStr.a_tool_tip = br.ReadString();
skillStr.a_descr1 = br.ReadString();
skillStringList.Add(skillStr);
string test = skillStr.a_index + "- " + skillStr.a_name;
listBox1.Items.Add(test);
}
EnableFields();
}
fs.Close();
br.Close();
}
I wrote a small test on my core i5 machine. New form, one button, one listbox:
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 30000; i++)
listBox1.Items.Add(i.ToString());
}
(I wrote it guessing at the index numbers in your screenshot). Clicked go. Had to wait 11 seconds before the UI became usable again.
I modified it to this:
private void button1_Click(object sender, EventArgs e)
{
listBox1.BeginUpdate();
for (int i = 0; i < 30000; i++)
listBox1.Items.Add(i.ToString());
listBox1.EndUpdate();
}
And there was a barely perceptible delay before it was usable again
The majority of the problem isn't reading the file, it's having the listbox refresh itself X thousands of times as you add one by one. Use Begin/End update to signal that you're loading a large amount of items...
...but then again, ask yourself what is a user REALLY going to do with X tens of thousands of items in a listbox? As a UI/UX guideline, avoid loading more than about 20 to 30 items into a list. Beyond that it's getting into unnavigable, especially at the quantities you're loading. Consider a type to search box - a one pixel jump of the scroll bar is going to move through more items than can fit vertically in your list!
If you're loading a lot of data from a file (or anywhere) into a list box, consider using the VirtualList approach - an example can be found here:
ListView.VirtualMode Property
You probably also want to consider performing the load in a background thread so that the user doesn't experience the apparent "hanging" delay that loading a lot of data can produce.
Listbox.beginupdate() and listbox.endupdate() fixed my problem thanks for the help guys.
I'm reading a file that is looking like that with a lot of strings
PrId Name Quantity Price Date
3 Milk 2 100 23-08-15
I have a button - btnDat_Click. When i click it retrieves all the dates in a listbox named listDate. I create a button named btnDataToTb_Click, i need to select the date and when i click the button it gonna show properties(Id, Name,Quantity) of all products of that date.
PrId Name Quantity Price
3 Milk 2 100
That's the whole code
char[] cc = new char[500]; int i, nr;
string[] lines = new string[250];
public void btnRead_Click(object sender, EventArgs e)
{
string FileName = textBox1.Text;
FileStream r_stream = new FileStream(FileName, FileMode.Open, FileAccess.ReadWrite);
StreamReader reads_string_from_r_stream = new StreamReader(r_stream);
i = 0;
listBox1.Items.Clear();
listBox2.Items.Clear();
for (; ; i++)
{
textBox1.Text = reads_string_from_r_stream.ReadLine();
lines[i] = textBox1.Text;
listBox1.Items.Add(lines[i]);
listBox2.Items.Add(lines[i]);
if (reads_string_from_r_stream.EndOfStream.Equals(true)) goto nn;
}
nn:
textBox2.Text = reads_string_from_r_stream.EndOfStream.ToString();
r_stream.Close();
nr = listBox1.Items.Count;
textBox6.Text = nr.ToString();
}
private void SelectPath_Click(object sender, EventArgs e)
{
OpenFileDialog openFile1 = new OpenFileDialog();
openFile1.Filter = "Text Files|*.txt";
if (openFile1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
textBox1.Text = openFile1.FileName;
}
public void button1_Click(object sender, EventArgs e)
{
int n = Convert.ToInt16(textBox6.Text);
ListB.Items.Clear();
for (i = 0; i < n; i++)
{
ListB.Items.Add(lines[i]);
}
}
private void btnDat_Click(object sender, EventArgs e)
{
int n = Convert.ToInt16(textBox6.Text);
for (i = 0; i < n; i++)
{
if(! listDate.Items.Contains(lines[i].Split('\t')[lines[i].Split('\t').Length - 1]))
{
listDate.Items.Add(lines[i].Split('\t')[lines[i].Split('\t').Length - 1]);
}
}
listData.Items.RemoveAt(0);
}
private void btnDataToTb_Click(object sender, EventArgs e)
{
if (listData.SelectedItems.Count > 0)
{
string data = listData.SelectedItem.ToString();
string[] date = data.Split('-');
int day = Convert.ToInt32(date[0]);
int month = Convert.ToInt32(date[1]);
int year = Convert.ToInt32(date[2]);
DateTime a = new DateTime(year, month, day);
for (i = 0; i < listBox2.Items.Count; i++)
{
DateTime data2 = DateTime.Parse(lines[i].Split('\t')[lines[i].Split('\t').Length - 1]);
int result = DateTime.Compare(a, data2);
if(result == 0)
listBox3.Items.Add(string.Format("{0}\t{1}\t{2}\t{3}", lines[i].Split('\t')[0], lines[i].Split('\t')[1], lines[i].Split('\t')[2], lines[i].Split('\t')[3]));
}
}
else
{
MessageBox.Show("Select a date");
}
}
I'd say you're approaching this problem wrong. Instead of reading the data, storing them in a list box, then reading and parsing them again when you need to, which is really complicated, you should rather do this:
Create a new class (e.g. Item) that has properties for the product id, name, quantity, price, and date.
When reading the data, parse the lines immediately and create a new instance of said class for each line. Store these in a List<Item>.
When working with FileStream, StreamReader etc (anything that implements IDisposable/has a Dispose() method) you should use them in a using block (like using (StreamReader sr = …) { /* work with sr here */ }); this will automatically free the object after use.
For making data visible to the GUI, you can either use data binding, or fill the listbox by hand and get the selected item with SelectedIndex.
Use Linq for querying data. To select all items on a specific date you can use var onThisDate = itemList.Where(item => item.Date == selectedDate). Linq has many more functions for selecting, filtering and projecting data.
private void button1_Click(object sender, EventArgs e)
{
double temp = double.Parse(textBox1.Text);
if (temp < 0)
{
label2.Text = "Freezing.";
}
if (temp > 40)
{
label2.Text = "Hot.";
}
else
{
label2.Text = "Moderate.";
}
}
Whenever converting user input, or any form of type String in to an object, I always like to use TryParse(...) as it provides you with better control if something isn't right.
double temp = 0.0d;
var converted = double.TryParse(textBox1.Text, out temp);
if (!converted) throw new Exception("Please enter a positive or negative temperature.");
if (temp < 0.0d)
{
// Freezing
}
else if (temp >= 0.0d && temp < 40.0d)
{
// Moderate
}
else if (temp >= 40.0d)
{
// Hot
}
The key is finding out what the value is being read in to temp. If its bringing in a negative number then I would recommend the code change below. What its really doing is if the 1st isnt true, then it checks the second, and finally it uses the third if neither are true.
private void button1_Click(object sender, EventArgs e)
{
double temp = double.Parse(textBox1.Text);
if (temp < 0)
{
label2.Text = "Freezing.";
}
else if (temp > 40)
{
label2.Text = "Hot.";
}
else
{
label2.Text = "Moderate.";
}
}
Ok I tried several codes. I just can't figure out what to do here..
I am doing a quiz. I save the questions and answers like that.
private void btnsave_Click(object sender, EventArgs e)
{
//checking if question or answer textbox are empty. If they are not then the question is saved
if (txtquestion.Text != "" & txtanswer.Text != "")
{
//saves the question in the questions text
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Users\User\Desktop\Assignment 2 Solo part\Questions.txt", true))
{
file.WriteLine(txtquestion.Text);
}
//saves the answer in the answers text
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Users\User\Desktop\Assignment 2 Solo part\Answers.txt", true))
{
file.WriteLine(txtanswer.Text);
}
MessageBox.Show("Question and Answer has been succesfully added in the Quiz!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.None);
//cleaning the textboxes for a new question and answer
txtanswer.Text = "";
txtquestion.Text = "";
}
//checks if the question textbox is empty and shows the corresponding message
else if (txtquestion.Text == "")
MessageBox.Show("Please enter a question", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
else //checks if the answer textbox is empty and shows the corresponding message
if (txtanswer.Text == "")
MessageBox.Show("Please enter an answer", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
until here everything is fine. The problem is after I delete a question there are empty lines in the file and I tried lots of stuff. I changed 2 times the way i save them. still I can make it work. Now I am also getting an out of bounds error when i delete a question because of the empty spaces that are created.
Here is the delete code:
private void fmrdelete_Load(object sender, EventArgs e)
{//declaration
int i=0;
//loading values to array from file
string[] qlines = System.IO.File.ReadAllLines(#"C:\Users\User\Desktop\Assignment 2 Solo part\Questions.txt").ToArray();
foreach (string line in qlines)
{
Console.WriteLine(line);
//saving each line to array possition
questions[i] = line;
i++;
lstboxquestions.Items.Add(line);
}
i = 0;
//loading values to array from file
string[] alines = System.IO.File.ReadAllLines(#"C:\Users\User\Desktop\Assignment 2 Solo part\Answers.txt").ToArray();
foreach (string line in alines)
{
Console.WriteLine(line);
//saving each line to array possition
answers[i] = line;
i++;
}
}
private void btndelete_Click(object sender, EventArgs e)
{
//declarations
int line_to_delete;
int count;
int i=0;
//changing the value given from textbox to integer and then saving it
line_to_delete = Convert.ToInt32(txtans.Text);
//checking to find the question we want to delete
for (count = 0; count < 20; count++)
{
if (count == (line_to_delete-1))
{
questions[count]= "";
}
}
//clearing file
System.IO.File.WriteAllText(#"C:\Users\User\Desktop\Assignment 2 Solo part\Questions.txt",string.Empty);
//saving to file
for (count = 0; count < 20; count++)
{
//saves the question in the questions text
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Users\User\Desktop\Assignment 2 Solo part\Questions.txt", true))
{
file.WriteLine(questions[count]);
}
}
//clearing the listbox
lstboxquestions.Items.Add(" ");
//loading from file back to array
string[] qlines = System.IO.File.ReadAllLines(#"C:\Users\User\Desktop\Assignment 2 Solo part\Questions.txt").ToArray();
foreach (string line in qlines)
{
line.Replace("\n\n", "\n");
Console.WriteLine(line);
//saving each line to array possition
questions[i] = line;
i++;
lstboxquestions.Items.Add(line);
}
//checking to find the answers we want to delete
for (count = 0; count < 20; count++)
{
if (count == (line_to_delete - 1))
{
answers[count] = "";
}
}
//clearing file
System.IO.File.WriteAllText(#"C:\Users\User\Desktop\Assignment 2 Solo part\Answers.txt", string.Empty);
//saving to file
for (count = 0; count < 20; count++)
{
//saves the question in the questions text
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\Users\User\Desktop\Assignment 2 Solo part\Answers.txt", true))
{
file.WriteLine(answers[count]);
}
}
string[] alines = System.IO.File.ReadAllLines(#"C:\Users\User\Desktop\Assignment 2 Solo part\Answers.txt").ToArray();
foreach (string line in alines)
{
Console.WriteLine(line);
//saving each line to array possition
answers[i] = line;
i++;
}
}
}
So how to remove the empty lines ?
When you delete line and then save to file instead of:
file.WriteLine(questions[count]);
try:
if(!string.IsNullOrWhiteSpac(questions[count]))
file.WriteLine(questions[count]);
Do the same with answers.
EDIT:
Have you tried insted of:
file.WriteLine(answers[count]);
this:
if(!string.IsNullOrWhiteSpac(answers[count]))
file.WriteLine(answers[count]);
here is my code
private void Allocation_Matrix_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13)
{
int Total_Row_Check;
Total_Row_Check = getRow();
Textbox1.Text = Convert.ToString(Total_Row_Check);
if (Total_Row_Check >= Convert.ToInt32(Total_Processes.Text))
{
MessageBox.Show("rows cannot exceed from total number of processess");
}
}
}
public int getRow()
{
int Row = 0;
string[] arLines;
int i;
arLines = Allocation_Matrix.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
for (i = 0; i < arLines.Length; i++)
{
Row++;
}
return Row;
}
i want to update TextBox1 as i hit ENTER in richtextbox from keyboard...but Textbox keeps show only FirstRow and shows One(1)
How about using RichTextBox.GetLineFromCharIndex Method? It returns, the zero-based line number in which the character index is located.
Is Allocation_Matrix your RichTextBox?
Note that RichTextBox.Text returns the text with line feed ("\n") for the line breaks, where most all other Windows controls use a carriage return, line feed ("\r\n").
So if you are calling Split on the string returned by the Text property, it won't contain any Evironment.NewLine.
try Allocation_Matrix.Text.Lines.Count() method
try this
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
var lineCount = richTextBox.Lines.Count();
numberLabel.Text = lineCount.ToString();
}