Sorting data from file in order from StreamReader - c#

I have a windows form that uses a StreamReader to read form data into some text boxes. That works perfectly fine. The problem now is that I want to display the data from the file in order alphabetically by names. Early I tried an array.Sort method, by it didn't work so well.
Here is my code:
Note: I close the reader and file in the dispose method.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace ViewArchives
{
public partial class Form1 : Form
{
const char DELIM = ',';
const string FILENAME = #"F:\lscSpring2016\CIS2620\FinalProject\TicketMaster\bin\Debug\SoldTickets.txt";
string recordIn;
string[] fields;
static FileStream file = new FileStream(FILENAME, FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(file);
public Form1()
{
InitializeComponent();
}
private void btnView_Click(object sender, EventArgs e)
{
try
{
recordIn = reader.ReadLine();
fields = recordIn.Split(DELIM);
nameBox.Text = fields[0];
ticketsBox.Text = fields[1];
purchaseBox.Text = fields[2];
dateBox.Text = fields[3];
}
catch (NullReferenceException)
{
label5.Text = "You have viewed\nall the records filed.";
btnView.Enabled = false;
}
}
}
}

There is a simpler way.
First, introduce a class for containing data from a single line:
class Record
{
public string Name { get; set; }
public string Tickets { get; set; }
public string Purchase { get; set; }
public string Date { get; set; }
}
In your Form1 class do the followings:
Create two fields.
One for the record list and one for indicating the current index in the record collection.
Record[] soldTickets; // This will contain the file data
int currentRecordIndex = -1;
Create a method that loads the whole file in one step into the record collection:
private void LoadRecords()
{
soldTickets =
File
.ReadAllLines(FILENAME)
.Select(line =>
{
string[] data = line.Split(DELIM);
return
new Record()
{
Name = data[0],
Tickets = data[1],
Purchase = data[2],
Date = data[3]
};
})
.OrderBy(record => record.Name)
.ToArray();
currentRecordIndex = -1;
}
Then your button click event handler can look like this:
private void btnView_Click(object sender, EventArgs e)
{
Record currentRecord = soldTickets.ElementAtOrDefault(++currentRecordIndex);
if (currentRecord == null)
{
label5.Text = "You have viewed\nall the records filed.";
btnView.Enabled = false;
return;
}
nameBox.Text = currentRecord.Name;
ticketsBox.Text = currentRecord.Tickets;
purchaseBox.Text = currentRecord.Purchase;
dateBox.Text = currentRecord.Date;
}

Related

ListBoxes won't display data from StreamReader text files

I have the .txt files inside the project's debug folder but the listboxes still won't display any of the data.
I've already missed the due date for this project, I just have a very unhelpful professor and I'd love to learn what I did wrong. Thanks!
The overview of what I'm trying to do here is:
Display delimited data into three listboxes from three text files. When a user clicks on an item in the listbox, one line of additional data (an ID) will be displayed in a textbox underneath that listbox. All three listboxes are shown on the same form and all data is delimited using the same character.
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace LabDay2Modified
{
struct CustomersNames
{
public string custID;
public string firstName;
public string lastName;
public string accountID;
}
struct AccountNumbers
{
public string acctID;
public string accountType;
public string accountNumber;
public string accountAmt;
}
struct LoanInfo
{
public string loanID;
public string loanYears;
public string loanIntRate;
public string loanAmt;
public string customerID;
public string loanType;
}
public partial class Form1 : Form
{
private List<CustomersNames> customerList = new List<CustomersNames>();
private List<AccountNumbers> accountList = new List<AccountNumbers>();
private List<LoanInfo> loanList = new List<LoanInfo>();
public Form1()
{
InitializeComponent();
}
private void ReadCustFile()
{
try
{
StreamReader inputFile;
string line;
CustomersNames entry = new CustomersNames();
char[] delim = { ',' };
inputFile = File.OpenText("customers.txt");
while (!inputFile.EndOfStream)
{
line = inputFile.ReadLine();
string[] tokens = line.Split(delim);
entry.custID = tokens[0];
entry.firstName = tokens[1];
entry.lastName = tokens[2];
entry.accountID = tokens[3];
customerList.Add(entry);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ReadAcctFile()
{
try
{
StreamReader inputFile;
string line;
AccountNumbers entry = new AccountNumbers();
char[] delim = { ',' };
inputFile = File.OpenText("accounts.txt");
while (!inputFile.EndOfStream)
{
line = inputFile.ReadLine();
string[] tokens = line.Split(delim);
entry.acctID = tokens[0];
entry.accountNumber = tokens[1];
entry.accountType = tokens[2];
entry.accountAmt = tokens[3];
accountList.Add(entry);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void ReadLoanFile()
{
try
{
StreamReader inputFile;
string line;
LoanInfo entry = new LoanInfo();
char[] delim = { ',' };
inputFile = File.OpenText("loans.txt");
while (!inputFile.EndOfStream)
{
line = inputFile.ReadLine();
string[] tokens = line.Split(delim);
entry.customerID = tokens[0];
entry.loanID = tokens[1];
entry.loanType = tokens[2];
entry.loanYears = tokens[3];
entry.loanIntRate = tokens[4];
entry.loanAmt = tokens[5];
loanList.Add(entry);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void CustInfo()
{
foreach(CustomersNames entry in customerList)
{
customerListBox.Items.Add(entry.custID + " " + entry.firstName + " " + entry.lastName);
}
}
private void AcctInfo()
{
foreach (AccountNumbers entry in accountList)
{
accountListBox.Items.Add(entry.accountNumber + " " + entry.accountType + " " + entry.accountAmt);
}
}
private void LoansInfo()
{
foreach (LoanInfo entry in loanList)
{
loanListBox.Items.Add(entry.loanID + " " + entry.loanType + " " + entry.loanYears+" "+entry.loanIntRate+" "+entry.loanAmt);
}
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Close();
}
private void customerListBox_SelectedIndexChanged(object sender, EventArgs e)
{
int index = customerListBox.SelectedIndex;
customerAccountID.Text = "Account ID: " + customerList[index].accountID;
}
private void loanListBox_SelectedIndexChanged(object sender, EventArgs e)
{
int index = loanListBox.SelectedIndex;
loanCustomerID.Text = "Customer ID: " + loanList[index].customerID;
}
private void accountListBox_SelectedIndexChanged(object sender, EventArgs e)
{
int index = accountListBox.SelectedIndex;
accountAccountID.Text = "Account ID: " + accountList[index].acctID;
}
private void Form1_Load(object sender, EventArgs e)
{
ReadCustFile();
CustInfo();
ReadAcctFile();
AcctInfo();
ReadLoanFile();
LoansInfo();
}
}
}
You can use the following .txt file to see if it works for you.
Then, you will get the following result.
Besides, you can set the similar style for other txt files.

Using OpenFileDialog and StreamReader

There are two classes, one to cover the form (class 1) and the other to cover what gets displayed on the form (class 2). I'm trying to call a method in class 1 from class 2 to display certain information in a text box. I keep getting the error:
An object reference is required for the non-static field, method, or property
I've encountered this error before and been able to make it through, but nothing I've attempted so far has helped in this instance. I'm posting code for both the classes.
Class 1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
namespace Project6
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
Stream myStream = null;
//Create an instance of the open file dialog box
OpenFileDialog ofd = new OpenFileDialog();
//Set parameters, filter options, and filter index
ofd.InitialDirectory = "c:\\";
ofd.Filter = "Text Files (.txt)|*.txt";
ofd.FilterIndex = 2;
ofd.Multiselect = false;
if (ofd.ShowDialog() == DialogResult.OK)
{
try
{
if ((myStream = ofd.OpenFile()) != null)
{
using (myStream = ofd.OpenFile())
{
StreamReader reader = new StreamReader(myStream);
string studentInformation = "";
string[] studentInformationArray = new string[11];
studentInformation = reader.ReadLine();
while ((studentInformation = reader.ReadLine()) != null)
{
studentInformationArray = studentInformation.Split(',');
Student newStudent = new Student(studentInformationArray);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
}
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox1.Text = Student.GetName(); //This generates the compiler error
textBox1.Select(6, 5);
MessageBox.Show(textBox1.SelectedText);
}
}
}
Class 2:
using System;
using System.Windows.Forms;
namespace Project6
{
class Student
{
//Initialize variables
private string[] studentInformationArray;
//Constructor that accepts the studentInformationArray as an argument
public Student(string[] studentInformationArray)
{
this.studentInformationArray = studentInformationArray;
}
public Student()
{
string className = studentInformationArray[1];
string semester = studentInformationArray[2];
string picture = studentInformationArray[3];
int project1 = Convert.ToInt32(studentInformationArray[4]);
int project2 = Convert.ToInt32(studentInformationArray[5]);
int project3 = Convert.ToInt32(studentInformationArray[6]);
int project4 = Convert.ToInt32(studentInformationArray[7]);
int project5 = Convert.ToInt32(studentInformationArray[8]);
int project6 = Convert.ToInt32(studentInformationArray[9]);
int midtermExam = Convert.ToInt32(studentInformationArray[10]);
int finalExam = Convert.ToInt32(studentInformationArray[11]);
}
public string GetName()
{
string studentName;
studentName = studentInformationArray[0];
return studentName;
}
}
}
That's because that's not how you use the OpenFileDialog. Take a look at this example hosted by the MSDN here:
Edit: answering to your edited question. You will always get a NullReferenceException in the Student() constructor because you are never assigning something to your studentInformationArray. So you can fix it like this:
public Student()
{
studentInformationArray = new studentInformationArray[12];
string className = studentInformationArray[1];
// rest of your code...
}
However, you should take into account that studentInformationArray will be an empty array unless you assign something to it. Since you have a Student() overload that takes a string[], I'd suggest you that you either remove the default constructor or make it call the overloaded with default information, like this:
public Student(string[] studentInformationArray)
{
string className = studentInformationArray[1];
// rest of your code...
int project1 = int.Parse(studentInformationArray[4]); // always prefer int.Parse() instead of Convert.ToInt32()
// rest of your code...
this.studentInformationArray = studentInformationArray;
}
public Student()
{
string[] defaultInformation = new string[12];
// add information
defaultInformation[0] = "some information";
// ...
new Student(defaultInformation);
}
Some more points to take into account:
Class-level fields/properties should be spelled in Pascal Case (first letter of each word in uppercase, rest in lowercase)
Try to never use this.variableName = variableName.
Variables names should never include the type of the variable, that's redundant.
So, for example, change this:
private string[] studentInformationArray;
for this:
private string[] StudentInformation;
Answering your last question, regarding the compiler error, you need a reference to the Student read in order to get its name. You could do something like this:
public partial class Form1 : Form
{
private Student StudentRead;
// rest of your code...
// from your read method:
StudentRead = new Student(studentInformationArray);
// and finally:
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox1.Text = StudentRead.GetName();

Entering data into Excel worksheets in an add in (C#)

I'm creating an add in for Microsoft Excel that includes a ribbon tab. On this tab is a button with the following code:
public void setAccounts()
{
foreach (Excel.Worksheet displayWorksheet in Globals.ThisAddIn.Application.Worksheets)
{
displayWorksheet.Range[budget_cell].Value2 = "$" + Convert.ToString(budget);
displayWorksheet.Range[account_cell].Value2 = "$0.00";
displayWorksheet.Range[transaction_cell].Value2 = "Amount";
}
}
The button opens up a separate form where the user specifies budget_cell, account_cell, and transaction_cell. I then pass that data to the above code in SolutionName.ThisAddIn.cs (where SolutionName is the namespace of the solution). Strictly speaking, the code works. However, the data doesn't show up in the cells until the button is pressed a second time. Why is that? Is it because I'm retrieving the data from a different object in the solution?
Also, I've been trying to get this code and the aforementioned form to activate when the add in first starts up.
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
frmStartup startup = new frmStartup();
startup.Show();
setAccounts();
}
I've been at this for a good twelve hours now, and I can't get it to work. What am I missing?
ThisAddIn.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Excel;
namespace AccountingAddIn
{
public partial class ThisAddIn
{
public static string budget_cell = "";
public static string account_cell = "";
public static string transaction_cell = "";
public static string date_cell = "";
public static string time_cell = "";
public static string description_cell = "";
public static bool date = false;
public static bool time = false;
public static bool description = false;
public static decimal budget = 0;
List<Account> accounts = new List<Account>();
public void budgetStartUp()
{
frmStartup startup = new frmStartup();
startup.Show();
setAccounts();
}
public void setAccounts()
{
foreach (Excel.Worksheet displayWorksheet in Globals.ThisAddIn.Application.Worksheets)
{
displayWorksheet.Range[budget_cell].Value2 = "$" + Convert.ToString(budget);
displayWorksheet.Range[account_cell].Value2 = "$0.00";
displayWorksheet.Range[transaction_cell].Value2 = "Amount";
if (date == true)
{
displayWorksheet.Range[date_cell].Value2 = "Date";
}
if (time == true)
{
displayWorksheet.Range[time_cell].Value2 = "Time";
}
if (description == true)
{
displayWorksheet.Range[description_cell].Value2 = "Description";
}
Account na = new Account(0, displayWorksheet);
accounts.Add(na);
}
}
protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
return Globals.Factory.GetRibbonFactory().CreateRibbonManager(
new Microsoft.Office.Tools.Ribbon.IRibbonExtension[] { new MyRibbon() });
}
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
CreateRibbonExtensibilityObject();
budgetStartUp();
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
}
}
}
frmStartup.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace AccountingAddIn
{
public partial class frmStartup : Form
{
public frmStartup()
{
InitializeComponent();
}
private void btnHelp_Click(object sender, EventArgs e)
{
MessageBox.Show("Please enter a starting amount for your budget and " +
"which cells will display the running total for your " +
"accounts." +
"\n\nNote: Leaving the budget blank will" +
" result in a starting budget of $0.00.");
}
private void btnOkay_Click(object sender, EventArgs e)
{
AccountingSeminar.ThisAddIn.budget += Convert.ToDecimal(txtStartingAmount.Text);
AccountingSeminar.ThisAddIn.budget_cell = txtBudget.Text;
AccountingSeminar.ThisAddIn.account_cell = txtAccount.Text;
AccountingSeminar.ThisAddIn.transaction_cell = txtTransaction.Text;
if (chkDate.Checked)
{
AccountingSeminar.ThisAddIn.date_cell = txtDate.Text;
AccountingSeminar.ThisAddIn.date = true;
}
if (chkTime.Checked)
{
AccountingSeminar.ThisAddIn.time_cell = txtTime.Text;
AccountingSeminar.ThisAddIn.time = true;
}
if (chkDescription.Checked)
{
AccountingSeminar.ThisAddIn.description_cell = txtDescription.Text;
AccountingSeminar.ThisAddIn.description = true;
}
Close();
}
}
}

Trying to read a text file into classes then cycle through

Hi am a fairly novice when it comes to c# and I have being trying to read out a text file then splitting it into sections with classes but have trouble with where to declare them an then how to cycle through the records. here's my code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;
using System.Windows.Forms;
namespace Assignment_3
{
public partial class Form1 : Form
{
string s;
string ss;
int i = 1;
string infilename;
int num;
SortedList sList = new SortedList();
int x = 0;
public Form1()
{
InitializeComponent();
student myself = new student();
infilename = "text.txt";
StreamReader sr1 = new StreamReader(infilename);
sList.Clear();
while ((s = sr1.ReadLine()) != null)
{
string[] strs = s.Split(',');
myself.firstname = strs[0];
myself.middlename = strs[1];
myself.surname = strs[2];
myself.dob = DateTime.Parse(strs[3]);
myself.dob.ToString(strs[3]);
myself.sex = strs[4];
ss = myself.dob.ToString("u");
sList.Add(myself.firstname, myself);
}
sr1.Close();
num = sList.Count;
student[] pArray = new student[num];
string[] keys = new string[num];
foreach (DictionaryEntry d in sList)
{
keys[x] = (string)d.Key;
pArray[x] = (student)d.Value;
x++;
}
if (i == 0)
{lblmessage.Text = "Already at the first record."; i = 1; }
if (i == num)
{lblmessage.Text = "Already at the last record.";i = num-1; }
lbllastname.Text = pArray[i].surname;
lblfirstname.Text = pArray[i].firstname;
lblsecondname.Text = pArray[i].middlename;
lbldob.Text = pArray[i].dob.ToString();
lblsex.Text = pArray[i].sex;
}
private void btnlast_Click(object sender, EventArgs e)
{
i = num;
}
private void btnfirst_Click(object sender, EventArgs e)
{
i = 0;
}
private void btnnext_Click(object sender, EventArgs e)
{
i++;
}
private void btnprev_Click(object sender, EventArgs e)
{
i--;
}
}
}
and my class file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Assignment_3
{
class student
{
public string firstname;
public string middlename;
public string surname;
public DateTime dob;
public string sex;
}
}
anyone have any ideas where am going wrong?? I have no errors but find that the text fields do not update with the new record's and then when stepped through the array class holds the correct amount of records and fields, I feel its going to be something very obvious put cant put my finger on it.
Any help would be very appreciated.
You should create new instance of student inside for loop. Because at the moment you have only one instance of student class and all items in SortedList are pointing to same object.

c# move item in listbox up and down

I got a windows form application with a listbox that display content, I wanna be able to move the items from the listbox up and down, when a button is clicked. at the moment the items in the list box stored are in text file, which is loaded into configuration class when the application start. How would I move the items up/down and change the order in the text file?
my main application form code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace company1
{
public partial class Form1 : Form
{
List<Configuration> lines = new List<Configuration>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.listBox1.Items.Clear();
//Read in every line in the file
using (StreamReader reader = new StreamReader("file.txt"))
{
string line = reader.ReadLine();
while (line != null)
{
string[] array = new string[] { "\\n" };
string[] parts = new string[3];
parts = line.Split(array, StringSplitOptions.RemoveEmptyEntries);
lines.Add(new Configuration(parts[0], int.Parse(parts[1]), int.Parse(parts[2])));
line = reader.ReadLine();
}
}
listBox1.DataSource = lines;
listBox1.DisplayMember = "CompanyName";
}
}
}
the configuration class file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace company1
{
class Configuration
{
string _CompanyName;
int _Employees;
int _Half;
public Configuration(string companyname, int number_of_Employees, int half)
{
_CompanyName = companyname;
_Employees = number_of_Employees;
_Half = half;
}
//program properties and validation
public string CompanyName
{
set
{
_CompanyName = value;
}
get
{
return _CompanyName;
}
}// End of levelname validation
//program properties and validation
public int EmployeesNumber
{
set
{
_Employees = value;
}
get
{
return _Employees;
}
}// End of levelname validation
//program properties and validation
public int Half
{
set
{
_Half = value;
}
get
{
return _Half;
}
}// End of levelname validation
}
}
any help appreciated, been trying for days to get it work.
// change the items in source list
var tmpLine = lines[10];
lines[10] = lines[9];
lines[9] = tmpLine;
// refresh datasource of listbox
listBox1.DataSource = null;
listBox1.DataSource = lines;
You could define an extension method for list to move items based on index:
public static class ExtensionClass
{
public static void Move<T>(this List<T> list, int index1, bool moveDown = true)
{
if (moveDown)
{
T temp = list[index1];
list[index1] = list[index1 + 1];
list[index1 + 1] = temp;
}
else
{
T temp = list[index1];
list[index1] = list[index1 - 1];
list[index1 - 1] = temp;
}
}
}
Then in Code you can:
List<int> list = new List<int> { 1, 2, 3, 4, 5, 6, 7 };
Console.WriteLine("Original List");
foreach (int i in list)
{
Console.Write(i + ",");
}
Console.WriteLine(Environment.NewLine + "Move Index 2 Down");
list.Move(2);
foreach (int i in list)
{
Console.Write(i + ",");
}
Console.WriteLine(Environment.NewLine + "Move Index 3 Up");
list.Move(3, false);
foreach (int i in list)
{
Console.Write(i + ",");
}
Output will be:
Original List
1,2,3,4,5,6,7,
Move Index 2 Down
1,2,4,3,5,6,7,
Move Index 3 Up
1,2,3,4,5,6,7,

Categories