Im trying to read some data from a csv file and display it in c#
this works fine but i have 2 different rows in my csv file which i'll be adding too.
I want them to be accessible if say someonet types '1' into the ukNumber field it will pull all of their data.
atm no matter what i type it always displays the last line in my csv file.
namespace Appraisal
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void ukNumber_TextChanged(object sender, EventArgs e)
{
}
public void search_Click(object sender, EventArgs e)
{
using (var reader = new StreamReader(File.OpenRead("C:\\Users\\hughesa3\\Desktop\\details.csv"),
Encoding.GetEncoding("iso-8859-1")))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',');
string idStr = values[0];
string firstnameStr = values[0];
string surnameStr = values[0];
string jobroleStr = values[0];
string salaryStr = values[0];
richTextBox1.Text = "Name: " + values[1] + "\nSurname: " + values[2] + "\nJob Role: " + values[3] + "\nSalary: £" + values[4];
}
}
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
private void apprasialCode_TextChanged(object sender, EventArgs e)
{
}
private void apprasialBtn_Click(object sender, EventArgs e)
{
}
private void ukNumberLabel_Click(object sender, EventArgs e)
{
}
}
}
There is a CsvHelper available via Nuget
https://www.nuget.org/packages/CsvHelper/
See following question:
using csvhelper (nuGET) with C# MVC to import CSV files
to read data from csv file:
using (var reader = new StreamReader(File.OpenRead("c:/yourfile.csv"),
Encoding.GetEncoding("iso-8859-1")))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';'); // replace ';' by the your separator
string idStr = values[0];
string firstnameStr = values[0];
string surnameStr = values[0];
string jobroleStr = values[0];
string salaryStr = values[0];
//convert string
}
}
Related
using System.IO;
namespace HW10
{
struct Employee
{
public string LastName;
public string FirstName;
public string IDNumber;
public string Department;
public string Position;
public string PayType;
public double HoursWorked;
public double PayRate;
}
public partial class frmPayroll : Form
{
//Create a list to hold the data from the input file
private List<Employee> EmployeeList = new List<Employee>();
public frmPayroll()
{
InitializeComponent();
}
private void frmPayroll_Load(object sender, EventArgs e)
{
}
private void btnOpen_Click(object sender, EventArgs e)
{
//Declare local variables
DialogResult ButtonClicked;
string InputRecord;
string[] InputFields;
Employee worker;
//Show the OpenFileDialog box for user to select file
openFileDialog1.InitialDirectory = Environment.CurrentDirectory;
openFileDialog1.FileName = "Payroll.csv";
ButtonClicked = openFileDialog1.ShowDialog();
if(ButtonClicked == DialogResult.Cancel)
{
MessageBox.Show("You did NOT select a file.");
return;
}
//Declare the streamreader variable to access the file
StreamReader inputFile = File.OpenText(openFileDialog1.FileName);
//Set up a loop to read every record, skipping the first record
InputRecord = inputFile.ReadLine();
while(!inputFile.EndOfStream)
{
InputRecord = inputFile.ReadLine();
InputFields = InputRecord.Split(',');
worker.LastName = InputFields[0];
worker.FirstName = InputFields[1];
worker.IDNumber = InputFields[2];
worker.Department = InputFields[3];
worker.Position = InputFields[4];
worker.PayType = InputFields[5];
worker.HoursWorked = double.Parse(InputFields[6]);
worker.PayRate = double.Parse(InputFields[7]);
//Add this worker struc to the list declared above
EmployeeList.Add(worker);
//Display the name in the Listbox on the form
listPayroll.Items.Add(worker.LastName + "," + worker.FirstName);
}
//Close the input file
inputFile.Close();
btnOpen.Enabled = false;
}
private void btnCompute_Click(object sender, EventArgs e)
{
listPayroll.Items.Clear();
string DisplayHeader = String.Format("{0,-18}{1,14}{2,11}{3,13}",
"Employee", "HoursWorked", "PayRate", "Gross Pay");
listPayroll.Items.Add(DisplayHeader);
DisplayHeader = String.Format("{0,-18}{1,14}{2,11}{3,13}",
"Employee", "HoursWorked", "PayRate", "Gross Pay");
listPayroll.Items.Add(DisplayHeader);
foreach (Employee emp in EmployeeList)
{
double HoursWorked = 0.0;
double PayRate = 0.0;
double GrossPay = 0.0;
// Check for Salary or Hourly
if(emp.PayType == "Hourly")
{
if(emp.HoursWorked > 40.0)
{
PayRate = emp.PayRate * (emp.HoursWorked - 40.0);
HoursWorked = emp.PayRate * 40.0;
}
else
{
PayRate = 0.0;
HoursWorked = emp.PayRate * emp.HoursWorked;
}
}
else //Salary paytype. No ot. Just striaght pay for 40 hrs
{
PayRate = 0.0;
HoursWorked = emp.PayRate * 40.0;
}
GrossPay = HoursWorked + PayRate;
//Display this data in the listbox
string DisplayPayroll = String.Format("{0,-18}{1,14:c}{2,11:C{3,13:c}",
emp.FirstName + " " + emp.LastName,
HoursWorked, PayRate, GrossPay);
listPayroll.Items.Add(DisplayPayroll);
}
}
private void btnExit_Click(object sender, EventArgs e)
{
// This method closes the application
this.Close();
I'm having issues when trying to compute data from a .csv file to a listbox. It's throwing an Exception unhandled error in the "Display this data in the listbox" block of code. I've place the System IO and all the strings/double that I need to show up in the list box. I'm sure this is a very simple fix but I'm new to coding. Any help would be greatly appreciated.
Using string.Split(',') isn't enough to handle CSV data. The CSV data can include fields that have commas in them:
https://en.wikipedia.org/wiki/Comma-separated_values
I'd suggest a CSV library to help parse the file. Google search of "c# csv library" should give you lots of options.
I have an application that allows the users to upload the selected images to the DataGridView and perform operations on their. However, when multiple images are selected, the Form freezes until the image information is uploaded to the DataGridView. I have tried BackgroundWorker for this, but it didn't work either. My codes look like this:
private void button1_Click(object sender, EventArgs e)
{
var file = new OpenFileDialog
{
Filter = #"TIFF |*.tiff| TIF|*.tif",
FilterIndex = 1,
Title = #"Select TIFF file(s)...",
Multiselect = true
};
if (file.ShowDialog() == DialogResult.OK)
{
Listing(file.FileNames);
}
}
private void Listing(string[] files)
{
foreach (var file in files)
{
var pic_name = Path.GetFileName(file);
if (file != null)
{
// Image from file
var img = Image.FromFile(file);
// Get sizes of TIFF image
var pic_sizes = img.Width + " x " + img.Height;
// Get size of TIFF image
var pic_size = new FileInfo(file).Length;
//Create the new row first and get the index of the new row
var rowIndex = dataGridView1.Rows.Add();
//Obtain a reference to the newly created DataGridViewRow
var row = dataGridView1.Rows[rowIndex];
//Now this won't fail since the row and columns exist
row.Cells["name"].Value = pic_name;
row.Cells["sizes"].Value = pic_sizes + " pixels";
row.Cells["size"].Value = pic_size + " bytes";
}
}
}
How can I solve this problem?
EDIT: After Alex's comment, I tried like this:
private void button1_Click(object sender, EventArgs e)
{
var file = new OpenFileDialog
{
Filter = #"TIFF |*.tiff| TIF|*.tif",
FilterIndex = 1,
Title = #"Select TIFF file(s)...",
Multiselect = true
};
if (file.ShowDialog() == DialogResult.OK)
{
_ = Test(file.FileNames);
}
}
private async Task Test(string[] s)
{
await Task.Run(() => Listing(s));
}
private void Listing(string[] files)
{
BeginInvoke((MethodInvoker) delegate
{
foreach (var file in files)
{
var pic_name = Path.GetFileName(file);
if (file != null)
{
// Image from file
var img = Image.FromFile(file);
// Get sizes of TIFF image
var pic_sizes = img.Width + " x " + img.Height;
// Get size of TIFF image
var pic_size = new FileInfo(file).Length;
//Create the new row first and get the index of the new row
var rowIndex = dataGridView1.Rows.Add();
//Obtain a reference to the newly created DataGridViewRow
var row = dataGridView1.Rows[rowIndex];
//Now this won't fail since the row and columns exist
row.Cells["name"].Value = pic_name;
row.Cells["sizes"].Value = pic_sizes + " pixels";
row.Cells["size"].Value = pic_size + " bytes";
}
}
});
}
But unfortunately the result is same.
I think the whole problem is in collecting image datas. Because a ready list will not take longer to load if it will not need extra processing. For this reason, I prepared a scenario like below.
private readonly BindingList<Tiff> _tiffs = new BindingList<Tiff>();
private void button1_Click(object sender, EventArgs e)
{
Listing();
}
private void Listing()
{
foreach (var f in _tiffs)
{
if (f != null)
{
var rowIndex = dataGridView1.Rows.Add();
//Obtain a reference to the newly created DataGridViewRow
var row = dataGridView1.Rows[rowIndex];
//Now this won't fail since the row and columns exist
row.Cells["ColName"].Value = f.ColName;
row.Cells["ColSizes"].Value = f.ColSizes + " pixels";
row.Cells["ColSize"].Value = f.ColSize + " bytes";
}
}
}
public static List<string> Files(string dir, string ext = "*.tiff")
{
var DirInfo = new DirectoryInfo(dir);
return DirInfo.EnumerateFiles(ext, SearchOption.TopDirectoryOnly).Select(x => x.FullName).ToList();
}
public void SetSource()
{
// Source folder of images...
var files = Files(#"___SOURCE_DIR___");
var total = files.Count;
var i = 1;
foreach (var file in files)
{
var pic_name = Path.GetFileName(file);
var img = Image.FromFile(file);
// Get sizes of TIFF image
var pic_sizes = img.Width + " x " + img.Height;
// Get size of TIFF image
var pic_size = new FileInfo(file).Length.ToString();
_tiffs.Add(new Tiff(pic_name, pic_sizes, pic_size));
BeginInvoke((MethodInvoker)delegate
{
label1.Text = $#"{i} of {total} is added to the BindingList.";
});
i++;
}
}
private void button2_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
SetSource();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Set something if you want.
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Set something if you want.
}
public class Tiff
{
public Tiff(string name, string sizes, string size)
{
ColName = name;
ColSizes = sizes;
ColSize = size;
}
public string ColName { get; set; }
public string ColSizes { get; set; }
public string ColSize { get; set; }
}
And here is the result:
I develop simple application for renaming locally stored emails. Emails are loaded in a listbox and there is a button which does renaming. The problem is that I can rename three email and than the application crushes. No specific error reported. Here is my code...
namespace EmailFilenameRename
{
public partial class Form1 : Form
{
CultureInfo deCulture = new CultureInfo("de-DE");
public Form1()
{
InitializeComponent();
}
private static string[] getAddressParts(string address)
{
var splittedAdress = address.Split(' ');
return splittedAdress.Last().Trim().StartsWith("<")
? new[] { string.Join(" ", splittedAdress.Take(splittedAdress.Length - 1)), splittedAdress.Last().Trim(' ', '<', '>') }
: splittedAdress;
}
private void Form1_Load(object sender, EventArgs e)
{
DirectoryInfo d = new DirectoryInfo(#"C:\...\in");
FileInfo[] Files = d.GetFiles("*.eml");
foreach (FileInfo file in Files)
{
listBox1.Items.Add(file.Name);
}
}
private void button1_Click(object sender, EventArgs e)
{
string oldName = #"C:\...\in\" + listBox1.GetItemText(listBox1.SelectedItem);
var mail = Sasa.Net.Mail.Message.Parse(File.ReadAllText(oldName));
string dt = mail.Headers["Date"].ToString();
DateTimeOffset originalTime = DateTimeOffset.Parse(dt, deCulture);
DateTime utcTime = originalTime.UtcDateTime.ToLocalTime();
string sTime = utcTime.ToString("yyyyMMdd HHmm");
string[] sFrom = getAddressParts(mail.From.ToString());
string sSubject = mail.Subject.Replace(":", "");
String newName = #"C:\...\in\renamed\" + sTime + " -- " + sFrom[1] + " -- " + sSubject + ".eml";
File.Copy(oldName, newName);
File.Delete(oldName);
}
}
}
I have also tried with MimeKit... the same problem exists.
I'm writing a Chat Program in C# (Windows Forms Application), the solution contains to projects which both consist of one form ( see picture ). While sending messages to each other works, I'm trying to record the conversation session in a .txt file named dateTime.txt using StreamWriter. Creating the file if it does not exist yet works, but whenever I open the text file, it only contains the last string that was written to it instead of containing the whole "conversation".
Does anybody know how to fix this?
This is the code of one of the forms, but since the forms do exactly the same, the code is the same too so i'm only posting the code of one Form. Would be great if somebody knows what I have to change so the whole conversation is recorded in the text file.
namespace Assignment3Client
{
public partial class Chat : Form
{
NamedPipeClientStream clientPipe = new NamedPipeClientStream("pipe2");
NamedPipeServerStream serverPipe = new NamedPipeServerStream("pipe1");
string msg = String.Empty;
string msgStr;
string name;
byte[] ClientByte;
public Chat()
{
InitializeComponent();
}
private void btnStartChat_Click(object sender, EventArgs e)
{
this.Text = "Waiting for a connection....";
if (txtBoxName.Text.Length == 0)
{
MessageBox.Show("please enter a name first.");
}
else
{
name = txtBoxName.Text;
clientPipe.Connect();
serverPipe.WaitForConnection();
if (serverPipe.IsConnected)
{
this.Text = "You are connected, " + name + "!";
btnStartChat.Enabled = false;
btnSend.Enabled = true;
txtBoxMsg.Enabled = true;
txtBoxMsg.Focus();
receiveWorker.RunWorkerAsync();
}
}
}
private void btnSend_Click(object sender, EventArgs e)
{
msg = "[" + name + ": " + DateTime.Now + "] " + txtBoxMsg.Text;
txtBoxChat.AppendText(msg + "\n");
FileWriter(msg);
sendWorker.RunWorkerAsync(msg); //start backgroundworker and parse msg string to the dowork method
txtBoxMsg.Clear();
txtBoxMsg.Focus();
}
private void sendWorker_DoWork(object sender, DoWorkEventArgs e)
{
Byte[] msgByte = System.Text.Encoding.GetEncoding("windows-1256").GetBytes(msg);
serverPipe.Write(msgByte, 0, msg.Length);
}
private void receiveWorker_DoWork(object sender, DoWorkEventArgs e)
{
ClientByte = new Byte[1000];
int i;
for (i = 0; i < ClientByte.Length; i++)
{
ClientByte[i] = 0x20;
}
clientPipe.Read(ClientByte, 0, ClientByte.Length);
msgStr = System.Text.Encoding.GetEncoding("windows-1256").GetString(ClientByte);
receiveWorker.ReportProgress(i, msgStr);
}
private void receiveWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if ((string)e.UserState == String.Empty)
{ MessageBox.Show("no message"); }
else
{
string message = (string)e.UserState;
txtBoxChat.AppendText(message);
FileWriter(message);
txtBoxChat.BackColor = System.Drawing.Color.DarkBlue;
txtBoxChat.ForeColor = System.Drawing.Color.White;
}
}
private void receiveWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (clientPipe.IsConnected)
{
receiveWorker.RunWorkerAsync();
}
else
{
txtBoxMsg.Enabled = false;
btnSend.Enabled = false;
MessageBox.Show("Connection lost");
}
}
private void Chat_Activated(object sender, EventArgs e)
{
txtBoxChat.BackColor = new System.Drawing.Color();
txtBoxChat.ForeColor = new System.Drawing.Color();
}
private void exitMenuStrip_Click(object sender, EventArgs e)
{
this.Close();
}
private void conMenuSrip_Click(object sender, EventArgs e)
{
}
private void errMenuStrip_Click(object sender, EventArgs e)
{
}
public void FileWriter(string message)
{
string path = #"C:\Users\selin\Documents\TAFE\Term 3\dateTime.txt";
FileStream conLog;
if (!File.Exists(path))
{
conLog = new FileStream(path, FileMode.Create);
}
else
{
conLog = new FileStream(path, FileMode.Open);
}
StreamWriter writer = new StreamWriter(conLog);
writer.WriteLine(message);
writer.AutoFlush = true;
writer.Close();
MessageBox.Show("written to file" + message);
}
}
}
in FileWriter(string message) change
conLog = new FileStream(path, FileMode.Open);
to
conLog = new FileStream(path, FileMode.Append);
I want to make a GUI for my device to show the value of each sensor. My device send data with this format
:1*895*123;
:1*987*145;
* is use to separate data from sensors
; is for the end of data
: is for start of data in next loop
I have variables dot, Rx1 and Ry2 to storing the data and show it on label, but looks like my program didn't works.. 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.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
string TestText, Rx1, Ry1, dot;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
serialPort1.PortName = "COM7";
serialPort1.BaudRate = 2400;
serialPort1.Open();
if (serialPort1.IsOpen)
{
button1.Enabled = false;
button2.Enabled = true;
}
}
private void button2_Click(object sender, EventArgs e)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
button1.Enabled = true;
button2.Enabled = false;
}
}
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
TestText = serialPort1.ReadExisting();
string[] nameArray = TestText.Split ('*');
foreach (string name in nameArray)
{
dot = nameArray[0];
Rx1 = nameArray[1];
Ry1 = nameArray[2];
}
}
private void label3_Click(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
label3.Text = dot;
posY.Text = Ry1;
posX.Text = Rx1;
}
//this.Invoke(new EventHandler(DisplayText));
}
}
I'm still new in c# and not so good with it.. so i need help. thanks before.
Are you sure that you're getting complete packets in the data received method? if not you'll need to buffer them up to be sure it's working properly.
You could try something like this.
// A buffer for the incoming data strings.
string buffer = string.Empty;
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
// buffer up the latest data.
buffer += serialPort1.ReadExisting();;
// there could be more than one packet in the data so we have to keep looping.
bool done = false;
while (!done)
{
// check for a complete message.
int start = buffer.IndexOf(":");
int end = buffer.IndexOf(";");
if (start > -1 && end > -1 && start < end)
{
// A complete packet is in the buffer.
string packet = buffer.Substring(start + 1, (end - start) - 1);
// remove the packet from the buffer.
buffer = buffer.Remove(start, (end - start) + 1);
// split the packet up in to it's parameters.
string[] parameters = packet.Split('*');
rx1 = parameters[0];
ry1 = parameters[1];
dot = parameters[2];
}
else
done = true;
}
If you getting just one chunk of data after reading. For example :1*895*123;
TestText = serialPort1.ReadExisting();//:1*895*123;
string[] nameArray = TestText.Split(new []{":", "*", ";"}, StringSplitOptions.RemoveEmptyEntries);
label3.Text = nameArray[0];//1
posY.Text = nameArray[1]; //895
posX.Text = nameArray[2]; //123
and if you receive :1*895*123; :1*987*145;
var chunks = s.Split(new [] { ":", ";", " "}, StringSplitOptions.RemoveEmptyEntries);
foreach (var chunk in chunks)
{
string[] data = chunk.Split(new [] { "*" }, StringSplitOptions.RemoveEmptyEntries);
label3.Text = data[0];
posY.Text = data[1];
posX.Text = data[2];
}
But then in labels you just see latest chunk data, so you need store a list of your data. For example you can create class:
class chunkData
{
public string dot;
public string posX;
public string posY;
}
and use it like this:
private List<chunkData> dataList = new List<chunkData>();
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
TestText = serialPort1.ReadExisting();
var chunks = TestText.Split(new [] { ":", ";", " "}, StringSplitOptions.RemoveEmptyEntries);
foreach (var chunk in chunks)
{
string[] data = chunk.Split(new [] { "*" }, StringSplitOptions.RemoveEmptyEntries);
dataList.Add(new chunkData(){dot=data[0], posX=data[1], posY=data[2]})
}
//display dataList to DataGridView or other control
}
EDIT: here is what you can do if you receiving data symbol by symbol:
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string temp = serialPort1.ReadExisting();
if(temp == ";") //OK we have end of data lets process it
splitAndDisplay();
else
TestText += temp;
}
private void splitAndDisplay()
{
string[] nameArray = TestText.Split(new []{":", "*"}, StringSplitOptions.RemoveEmptyEntries);
this.Invoke(new Action(() =>
{
label3.Text = nameArray[0];
posY.Text = nameArray[1];
posX.Text = nameArray[2];
}));
TestText = "";
}