Getting two bits of data into one c# windows form - c#

I have got the data from a text file to fill in the text boxes with the data. However I am trying to get an employees salary from another class into the text box and I am struggling to do so. My first class is the employee class with this code:
public class Employee
{
string _firstName;
string _lastName;
string _address;
string _postCode;
string _phoneNumber;
DateTime _dateOfBirth;
public Employee()
{
}
public Employee(string firstName, string lastName, string address, string postCode, string phoneNumber, DateTime dateOfBirth)
{
_firstName = firstName;
_lastName = lastName;
_address = address;
_postCode = postCode;
_phoneNumber = phoneNumber;
_dateOfBirth = dateOfBirth;
}
public string firstName
{
get
{
return _firstName;
}
set
{
_firstName = value;
}
}
public string lastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
}
}
public string address
{
get
{
return _address;
}
set
{
_address = value;
}
}
public string postCode
{
get
{
return _postCode;
}
set
{
_postCode = value;
}
}
public string phoneNumber
{
get
{
return _phoneNumber;
}
set
{
_phoneNumber = value;
}
}
public DateTime dateOfBirth
{
get
{
return _dateOfBirth;
}
set
{
_dateOfBirth = value;
}
}
followed by the salaried class with this code:
public class SalariedEmployee : Employee
{
decimal _salary;
public SalariedEmployee(string firstName, string lastName, string
address, string postCode, string phoneNumber, DateTime dateOfBirth,
decimal salary) : base(firstName, lastName, address, postCode, phoneNumber,
dateOfBirth)
{
_salary = salary;
}
public decimal salary
{
get
{
return _salary;
}
set
{
_salary = value;
}
}
}
this then goes onto the load method which is as follows:
public bool Load(string employeesFile)
{
List<string> lines = new List<string>();
using (StreamReader reader = new StreamReader("employees.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
//Splitting the data using |
string[] temp = line.Split('|');
int year = Convert.ToInt32(temp[5]);
int month = Convert.ToInt32(temp[6]);
int day = Convert.ToInt32(temp[7]);
//This is to populate an employees detials
Employee emp = new Employee
{
firstName = temp[0],
lastName = temp[1],
address = temp[2],
postCode = temp[3],
phoneNumber = temp[4],
dateOfBirth = new DateTime(year, month, day)
};
//This class is from List, so I used the add method to add the employee.
Add(emp);
}
return true;
and finally the form code:
public Salaried_Employee_Details(Employee emp)
{
InitializeComponent();
textBoxLastName.Text = emp.lastName;
textBoxFirstName.Text = emp.firstName;
textBoxAddress.Text = emp.address;
textBoxPostCode.Text = emp.postCode;
textBoxPhoneNumber.Text = emp.phoneNumber;
dateTimeDateOfBirth.Text = emp.dateOfBirth.ToString();
//textBoxSalary.Text = emp.salary;
}
with the work form here:
the format of the text file is here:
Smyth|Jack|London street, London City, London|01142325413|1990|3|21|37000
so how do I get the salaried data into the text box?

Looking at the split of your string into an array you either have no postal code or no number:
postCode = temp[3],
phoneNumber = temp[4],
Here are your indices of the array
Smyth|Jack|London street, London City, London|01142325413|1990|3|21|37000
^ ^ ^ ^ ^ ^ ^ ^
| | | | | | | |
0 1 2 3 4 5 6 7
In this case 4 looks for me like a year!
If the salary is on the last position you need distinguish between a normal Employee and a SalariedEmployee In the firs case you do it like you do already and in the second case you need to create a SalariedEmployee object when loading your data:
int year = Convert.ToInt32(temp[4]);
int month = Convert.ToInt32(temp[5]);
int day = Convert.ToInt32(temp[6]);
SalariedEmployee emp = new SalariedEmployee
{
firstName = temp[1],
lastName = temp[0],
address = temp[2],
phoneNumber = temp[3],
dateOfBirth = new DateTime(year, month, day)
salary = Convert.ToDecimal(temp[7]);
};
EDIT: What you need to make this code work is a parameterless constructor in the SalariedEmployee class.
public SalariedEmployee()
{
}
or you need to use the constructor that you have written with all the parameters:
public SalariedEmployee(string firstName, string lastName, string
address, string postCode, string phoneNumber, DateTime dateOfBirth,
decimal salary)
which would look like this:
SalariedEmployee emp = new SalariedEmployee(temp[1], temp[0],temp[2],
"I don't know where your postcode is",
temp[3],new DateTime(year, month, day),
Convert.ToDecimal(temp[7]));

There is no .salary property because the constructor is expecting an Employee:
public Salaried_Employee_Details(Employee emp)
Which doesn't have that property. However, SalariedEmployee does have that property. If the constructor needs a SalariedEmployee then simply change it to require one:
public Salaried_Employee_Details(SalariedEmployee emp)
Then you can use that property like any other:
textBoxSalary.Text = emp.salary;

Looks like there's a spot missing in the format of text file.
The string you posted
Smyth|Jack|London street, London City,
London|01142325413|1990|3|21|37000
has 7 separators, which lead to an array of 8 strings, the last of them (temp[7]) being the salary. Instead, in your code it is assigned to the day property of the Employee instance.
By the way, assuming there's actually another string with the postcode formatted like this
Smyth|Jack|London street, London City, London|L12
3AS|01142325413|1990|3|21|37000
you should declare emp as a SalariedEmployee class instance instead, and I recommend using the TryParse method to check whether the salary string can be converted into decimal.
public bool Load(string employeesFile)
{
bool isLoaded = false;
List<string> lines = new List<string>();
using (StreamReader reader = new StreamReader("employees.txt"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
//Splitting the data using |
string[] temp = line.Split('|');
int year = Convert.ToInt32(temp[5]);
int month = Convert.ToInt32(temp[6]);
int day = Convert.ToInt32(temp[7]);
//Populating the employees details
decimal _salary;
if (Decimal.TryParse(temp[8], out _salary))
{
SalariedEmployee emp = new SalariedEmployee(firstName: temp[1],
lastName: temp[0],
address: temp[2],
postCode: temp[3],
phoneNumber: temp[4],
dateOfBirth: new DateTime(year, month, day),
salary: _salary)
at this point, you need to also be sure the List parameter is changed to be of SalariedEmployee type, otherwise you'll get a compiler error in the following line
Add(emp);
isLoaded = true;
}
}
return isLoaded;
}
at this point, in the form you just need to change the type argument and un-check the last line of code
public Salaried_Employee_Details(SalariedEmployee emp)
{
InitializeComponent();
textBoxLastName.Text = emp.lastName;
textBoxFirstName.Text = emp.firstName;
textBoxAddress.Text = emp.address;
textBoxPostCode.Text = emp.postCode;
textBoxPhoneNumber.Text = emp.phoneNumber;
dateTimeDateOfBirth.Text = emp.dateOfBirth.ToString();
textBoxSalary.Text = emp.salary;
}
Hope this might help you.
Bye!
Davide.

Related

Checking if an object is on the list I created [duplicate]

This question already has answers here:
how to check if List<T> element contains an item with a Particular Property Value
(7 answers)
Closed 1 year ago.
I am making a code that registers a number of parameters and then checks if these parameters are already in the list, in the case, for example, I want to check if an Email is in this list, how can I do this check?
List<Professional> lprofessional = new List<Professional>();
public int role_id = 1;
public string First_name { get; set; }
public string Last_name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Description { get; set; }
public Professional(int role_id, string firstname, string lastname, string email, string phone, string description) {
this.First_name = firstname;
this.Last_name = lastname;
this.Email = email;
this.Phone = phone;
this.Description = description;
}
public void Create()
{
Professional pro = new Professional(role_id, First_name, Last_name, Email, Phone, Description);
if (lprofessional.Contains(email)//Here is the check maybe...
{
lprofessional.Add(pro);
role_id++;
}
}
if (lprofessional.Any(p => p.Email == email))
{
// already in the list
}
else
{
// not yet in the list
}
Alternatively:
var p = lprofessional.FirstOrDefault(p => p.Email == email);
if (p is object)
{
//already in the list, and you can use "p" to see or change other properties
}
else
{
// not in the list
}
I know there are also newer options using pattern matching to do this in even less code, but I've not yet incorporated pattern matching into my own workflow.
var email = "test#test.com";
var listElement = lprofessional.Where(x=> x.Email.Equals(email)).FirstOrDefault();
if(listElement != null)
{
//some code
}
or
var email = "test#test.com";
var result = lprofessional.Any(x => x.Email.Equals(email));
if( result)
{
//some code here
}

Having trouble with C# Properties, Constructors,and LINQ

The code below is not returning any values. I am trying to print customer name and balance where their balance is below $0. I believe my property may not be set the right way. I am new to object oriented programming and LINQ. Any help would be appreciable.
namespace LinqExample
{
class Customer
{
private string name, phone, address;
private int balance;
public string custData;
public string Name
{
get { return name; }
set { name = value; }
}
public string Phone
{
get { return phone; }
set { phone = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
public int Balance
{
get { return balance; }
set { balance = value; }
}
public Customer(string name, string phone, string address, int balance)
{
custData = name + phone + address + balance;
}
}
}
namespace LinqExample
{
class Program
{
static void Main(string[] args)
{
List<Customer> customers = new List<Customer>();
customers.Add(new Customer("Amit", "123-456-789", "123 Any Road", 25));
customers.Add(new Customer("Ajay", "571-888-1234", "1234 Any Street", 50));
customers.Add(new Customer("John", "707-123-4560", "456 John Street", -10));
customers.Add(new Customer("Ashley", "707-123-8402", "789 Ashley Street", -20));
var overdue =
from cust in customers
where cust.Balance < 0
orderby cust.Balance ascending
select new { cust.Name, cust.Balance };
foreach (var cust in overdue)
{
Console.WriteLine($"Name = {cust.Name}, Balance = {cust.Balance}");
}
}
}
}
You need to set the members values:
public Customer(string name, string phone, string address, int balance)
{
this.name = name;
this.phone = phone;
this.address = address;
this.balance = balance;
custData = name + phone + address + balance;
}
You're not setting any of your properties other than "custdata", you need to set the rest of the properties in your constructor too.
As others have stated you're not assigning any of your properties to the passed in ctor values.
Either do what Romano suggested or use an object initializer.
Assign the properties in the constructor.
public Customer(string name, string phone, string address, int balance)
{
this.name = name;
this.phone = phone;
this.address = address;
this.balance = balance;
custData = name + phone + address + balance;
}
Object Initilizer with a default ctor.
customers.Add(new Customer
{
Name = "Bill",
Phone = "555-555-5555",
Address = "2345 Some street",
Balance = "100000000"
});
As a side note, instead of using that public field "custData" try overriding the ToString method to return all of that concatenated data.

How do I manipulate an object's properties after it has been added to a List in C#

Say I have a class like this:
class public Person
{
public string firstName;
public string lastName;
public string address;
public string city;
public string state;
public string zip;
public Person(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
}
And let's further say I create a List of type Person like this:
List<Person> pList = new List<Person>;
pList.Add(new Person("Joe", "Smith");
Now, I want to set the address, city, state, and zip for Joe Smith, but I have already added the object to the list. So, how do I set these member variables, after the object has been added to the list?
Thank you.
You get the item back out of the list and then set it:
pList[0].address = "123 Main St.";
You can keep a reference to your object around. Try adding like this:
List<Person> pList = new List<Person>;
Person p = new Person("Joe", "Smith");
pList.Add(p);
p.address = "Test";
Alternatively you can access it directly through the list.
pList[0].address = "Test";
You can get the first item of the list like so:
Person p = pList[0]; or Person p = pList.First();
Then you can modify it as you wish:
p.firstName = "Jesse";
Also, I would recommend using automatic properties:
class public Person
{
public string firstName { get; set; }
public string lastName { get; set; }
public string address { get; set; }
public string city { get; set; }
public string state { get; set; }
public string zip { get; set; }
public Person(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
}
You'll get the same result, but the day that you'll want to verify the input or change the way that you set items, it will be much simpler:
class public Person
{
private const int ZIP_CODE_LENGTH = 6;
public string firstName { get; set; }
public string lastName { get; set; }
public string address { get; set; }
public string city { get; set; }
public string state { get; set; }
private string zip_ = null;
public string zip
{
get { return zip_; }
set
{
if (value.Length != ZIP_CODE_LENGTH ) throw new Exception("Invalid zip code.");
zip_ = value;
}
}
public Person(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
}
Quite possibly not the best decision to just crash when you set a property here, but you get the general idea of being able to quickly change how an object is set, without having to call a SetZipCode(...); function everywhere. Here is all the magic of encapsulation an OOP.
You can access the item through it's index. If you want to find the last item added then you can use the length - 1 of your list:
List<Person> pList = new List<Person>;
// add a bunch of other items....
// ....
pList.Add(new Person("Joe", "Smith");
pList[pList.Length - 1].address = "....";
Should you have lost track of the element you're looking for in your list, you can always use LINQ to find the element again:
pList.First(person=>person.firstName == "John").lastName = "Doe";
Or if you need to relocate all "Doe"s at once, you can do:
foreach (Person person in pList.Where(p=>p.lastName == "Doe"))
{
person.address = "Niflheim";
}

How do I take string values from a list of objects and add them to a drop down list?

I want to take a list of employees with 3 parts, employee id, last name and first name and add them to a drop down list showing last name, first name.
What I have so far is that I created a class for the employees:
public class Employee
{
public int emp_Id;
public string lastName;
public string firstName;
public Employee(int id, string last, string first)
{
this.emp_Id = id;
this.lastName = last;
this.firstName = first;
}
}
and created a list to populate:
private List<Employee> employeeList = new List<Employee>();
this list is populated from a sql query and then sorted by last name.
foreach (DataRow row in ds.Tables["EMPLOYEE_TABLE"].Rows)
{
employeeList.Add(new Employee(int.Parse(row["EMP_ID"].ToString()),
row["LAST_NAME"].ToString(), row["FIRST_NAME"].ToString()));
}
employeeList.Sort(delegate(Employee E1, Employee E2) { return E1.lastName.CompareTo(E2.lastName); });
and everything up to that point worked exactly as I wanted it to but I cannot figure out how I populate a dropdownlist with the last name and first name values contained in the list.
code has been edited for readability
See code below:
DropDownList ddl = new DropDownList();
ddl.DataSource = employeeList;
ddl.DataTextField = "fullName";
ddl.DataValueField = "emp_Id";
I would also modify your class to include a full name field:
public class Employee
{
public int emp_Id { get; set; }
public string lastName { get; set; }
public string firstName { get; set; }
public string fullName
{
get
{
return String.Format("{0} {1}", this.firstName, this.LastName);
}
}
public Employee(int id, string last, string first)
{
this.emp_Id = id;
this.lastName = last;
this.firstName = first;
}
}
You could add an extra property to your class that will hold the 3 values, and use this as your DataTextField when binding the DropDownList:
Class Code
public class Employee
{
public int emp_Id;
public string lastName;
public string firstName;
public string Text
{
get { return this.ToString(); }
}
public Employee(int id, string last, string first)
{
this.emp_Id = id;
this.lastName = last;
this.firstName = first;
}
public override string ToString()
{
return lastName + " " + firstName + " " + emp_Id;
}
}
HTML:
List<Employee> employees = new List<Employee>();
ddl.DataSource = employees;
ddl.DataValueField = "emp_Id";
ddl.DataTextField = "Text";
ddl.DataBind();
Good luck!
Example with existing properties:
<asp:DropDownList id="bla" runat="server" />
bla.DataSource = employeeList;
bla.DataTextField = "firstName";
bla.DataValueField = "emp_Id"
bla.DataBind();
I recommend this:
<asp:DropDownList id="bla" runat="server" />
bla.DataSource = employeeList;
bla.DataTextField = "fullName";
bla.DataValueField = "emp_Id"
bla.DataBind();
public class Employee
{
public int emp_Id;
public string lastName;
public string firstName;
public string fullName get{ return firstName + " " + lastName;}
public Employee(int id, string last, string first)
{
this.emp_Id = id;
this.lastName = last;
this.firstName = first;
}
}
Why don't you create a property called FullName to gets "FirstName + ' ' + LastName"? That would give you one field to deal with instead of two.
If you don't want or can't modify Employee, you may also try something along those lines:
var data = employee.Select (x =>
new KeyValuePair<int, string>(
x.emp_Id,
string.Format("{0}, {1}", x.lastName, x.firstName)
));
ddl.DataSource = data.ToList();
ddl.DataValueField = "Key";
ddl.DataTextField = "Value";
ddl.DataBind();
This may also be useful if you have different pages with different dropdowns for employees, sometimes with Lastname first, sometimes with Firstname first, and maybe with and without a colon in between ...

Display Data from a class

How can i show Data from a class into a gridview?
MY Class is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
public class EmployeeDetails
{
private int employeeID;
public int EmployeeID
{
get
{
return employeeID;
}
set
{
employeeID = value;
}
}
private string firstName;
public string FirstName
{
get
{
return firstName;
}
set
{
firstName = value;
}
}
private string lastName;
public string LastName
{
get
{
return lastName;
}
set
{
lastName = value;
}
}
private string titleOfCourtesy;
public string TitleOfCourtesy
{
get
{
return titleOfCourtesy;
}
set
{
titleOfCourtesy = value;
}
}
public EmployeeDetails(int employeeID, string firstName, string lastName, string titleOfCourtesy)
{
EmployeeID = employeeID;
FirstName = firstName;
LastName = lastName;
TitleOfCourtesy = titleOfCourtesy;
}
}
I`ve done this:
protected void Page_Load(object sender, EventArgs e)
{
int id = 15;
string f_name = "asd";
string l_name = "asd";
string title = "asd";
EmployeeDetails emp = new EmployeeDetails(id,f_name,l_name,title);
emp.EmployeeID = id;
emp.FirstName = f_name;
emp.LastName = l_name;
emp.TitleOfCourtesy = title;
}
List<EmployeeDetails> lst = new List<EmployeeDetails>() ;
GridView1.DataSource = lst ;
GrdiView1.DataBind();
you may populate the list with your EmployeeDetails Objects
A GridView is generally used to display multiple objects/rows. To get it to display your class you need to make a collection containing your class, such as a List<EmployeeDetails>. Then bind that to your gridview.
You could use another control more suited to displaying a single object such as a DetailsView.
I assume you are looking for an answer to show multiple item instead of just 1.
C#
var myList = List<EmploymentDetails>();
foreach (var employee in SomeOtherDataSource)
{
EmployeeDetails emp = new EmployeeDetails{EmployeeID = id, FirstName = f_name, LastName = l_name, TitleOfCourtesy = title};
myList.Add(emp);
}
var EmployeeDS = from eds in myList select new { ID = EmployeeID, FName = FirstName, LName = LastName, Title = TitleofCourtest };
MyGridview.DataSource = EmployeeDS;
MyGridView.DataBind();
By doing this: var EmployeeDS = from eds in myList select new { ID = EmployeeID, FName = FirstName, LName = LastName, Title = TitleofCourtest }; it makes it possible to just use <%# Eval('ID/FName/LName/Title'%> in the GridView's boundfields instead of those long variable names you've made in your entity class.

Categories