C# List access object and add name to list - c#

I'm trying to get all the names in a list and display them in a listbox. Here's my code.
namespace UniRecords
public partial class MainWindow
{
private University uni = new University(); //Creates a new University object
public MainWindow()
{
InitializeComponent();
}
private void btnadd_Click(object sender, RoutedEventArgs e)
{
Student newStudent = new Student(txtname.Text, txtaddress.Text, txtmatric.Text,txtcourse.Text); //Calls the student constructor to construct a student object
uni.ownsStudent(newStudent); //Calls the newStudent method in the University class
}
private void btnshow_Click(object sender, RoutedEventArgs e)
{
uni.showStudents(); //calls the showStudents method
}
private void btnlist_Click(object sender, RoutedEventArgs e)
{
}
}
}
My University class:
namespace UniRecords
class University
{
//Creates a list of students that University owns
private List<Student> owns = new List<Student>();
public University()
{
}
public void ownsStudent(Student newStudent)
{
owns.Add(newStudent);//Adds a new student to the list
}
public void showStudents()
{
foreach (Student s in owns)
{
System.Windows.MessageBox.Show(s.printDetails()); //Prints out details of each student individually
}
}
public void getStudents()
{
foreach (Student s in owns)
{
}
}
}
}
Student class:
namespace UniRecords
class Student
{
private string name;
private string dob; //Date of birth
private string course;
private string matric;
private string address;
//Constructor
public Student(string myname, string myaddress, string mymatric, string mycourse)
{
Name = myname;
Address = myaddress;
Matric = mymatric;
Course = mycourse;
}
//Uses get and set to make sure that the variables are kept private
public string Name
{
get { return name; }
set { name = value; }
}
public string Dob
{
get { return dob; }
set { dob = value; }
}
public string Course
{
get { return course; }
set { course = value; }
}
public string Matric
{
get { return matric; }
set { matric = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
public string printDetails()
{
return "student is called " + Name + " " + Address + " " + Matric + " " + Course;
}
public void listNames()
{
}
}
}
I'm trying to have btnlst_click be pressed and get output a list of all the names that have been inputted.
I know I need to use something like: foreach (Student s in owns) but I don't have permissions to do it from the mainwindow class and I'm not sure how I could pass it from the University class to mainwindow to be put in the string. Can someone offer advice?

You have to define your method to have it return a list of studentnames.
public List<string> GetStudents(){
return owns.Select(x => x.Name).ToList();
}
This roughly translates to
public List<string> GetStudents(){
var result = new List<String>();
foreach(var student in owns) {
result.add(student.Name);
}
return result;
}
This small LINQ expression will select all the names of the students and return it for you to use. Notice the List<string> return statement instead of void.
And in your main form class:
myListBox.DataSource = someUniversity.GetStudents():
I'm not familiar with GUI development in C#, so this assignment might look different.
Keep naming conventions in mind: methods are CamelCased!

Related

c# Creating a list with user input

I'm fairly new to c# and having difficulty with lists.
I'm creating an application that takes in a user's name, age, and address, then stores it in a list when the user clicks the 'add' button.
I'm using a GUI with text boxes for user input.
I have made a Customer class and unsure what to do next. I've followed tutorials and other questions but can't seem to find an answer.
public class Customer
{
private string name;
private Int32 age;
private string address1;
private string address2;
private string address3;
public string Name
{
get
{
return name;
}
// if name is blank throw argument asking user for input
set
{
if (name == "")
{
throw new ArgumentException("Please enter your name");
}
else
{
name = value;
}
}
}
public Int32 Age
{
get
{
return age;
}
set
{
age = value;
}
}
// get/set address
public string Address1
{
get
{
return address1;
}
set
{
if (address1 == "")
{
throw new ArgumentException("Please enter your address");
}
else
{
address1 = value;
}
}
}
public string Address2
{
get
{
return address2;
}
set
{
if (address2 == "")
{
throw new ArgumentException("Please enter your adress");
}
else
{
address2 = value;
}
}
}
public string Address3
{
get
{
return address3;
}
set
{
if (address3 == "")
{
throw new ArgumentException("Please enter your adress");
}
else
{
address3 = value;
}
}
}
This is an example of simple Windows Forms form that will give you an idea. Basically you would like to store the list of customers in private generic list variable. More about how to use generic and non-generic lists in C# here.
public partial class Form1 : Form
{
// Initialize private generic list where all customers will be stored at runtime
private List<Customer> _customers = new List<Customer>();
private void buttonAddCustomer_Click(object sender, EventArgs e)
{
// It might be a good idea to add some validation logic before assigning the input values
var newCustomer = new Customer();
newCustomer.Name = this.textBoxName.Text;
newCustomer.Age = Convert.ToInt32(this.textBoxAge.Text);
newCustomer.Address1 = this.textBoxAddress1.Text;
newCustomer.Address2 = this.textBoxAddress2.Text;
newCustomer.Address3 = this.textBoxAddress3.Text;
_customers.Add(newCustomer);
}
}
I think what you are looking for is in the MakeItHappen() method
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace _41150122
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn_Go_Click(object sender, EventArgs e)
{
MakeItHappen();
}
private void MakeItHappen()
{
List<Customer> customerList = new List<Customer>();//initialize your List<Customer>
customerList.Add(new Customer { Name = txtbx_Name.Text, Address1 = txtbx_Address1.Text, Age = int.Parse(txtbx_Age.Text) });//add a record to it
}
}
public class Customer
{
private string name;
private Int32 age;
private string address1;
private string address2;
private string address3;
public string Name
{
get
{
return name;
}
// if name is blank throw argument asking user for input
set
{
if (name == "")
{
throw new ArgumentException("Please enter your name");
}
else
{
name = value;
}
}
}
public Int32 Age
{
get
{
return age;
}
set
{
age = value;
}
}
// get/set address
public string Address1
{
get
{
return address1;
}
set
{
if (address1 == "")
{
throw new ArgumentException("Please enter your address");
}
else
{
address1 = value;
}
}
}
public string Address2
{
get
{
return address2;
}
set
{
if (address2 == "")
{
throw new ArgumentException("Please enter your adress");
}
else
{
address2 = value;
}
}
}
public string Address3
{
get
{
return address3;
}
set
{
if (address3 == "")
{
throw new ArgumentException("Please enter your adress");
}
else
{
address3 = value;
}
}
}
}
}

c# list.add() overwrite the object at position 0

i am updating my question to this
i created new class Student
class Student
{
private string _firstName;
private string _lastName;
private int _exam1;
private int _exam2;
private int _exam3;
private int _finalExam;
// First Name Property
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
//Last Name Property
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
//Exam 1 Property
public int Exam1
{
get { return _exam1; }
set { _exam1 = value; }
}
// Exam 2 Property
public int Exam2
{
get { return _exam2; }
set { _exam2 = value; }
}
//Exam 3 Property
public int Exam3
{
get { return _exam3; }
set { _exam3 = value; }
}
//Final Exam Property
public int FinalExam
{
get { return _finalExam; }
set { _finalExam = value; }
}
}
}
this is my add new student form class with one method to add new student
public class AddStudent : Form
{
StudentForm stu = null;
public AddStudent()
{
InitializeComponent();
stu = new StudentForm();
stu.Show();
}
private void btnSubmit_Click(object sender, EventArgs e)
{
// split the name into first and last name
string[] name = txtName.Text.Split(',');
Student std = new Student();
std.FirstName = name[0];
std.LastName = name[1];
std.Exam1 = Int32.Parse(txtExam1.Text);
std.Exam2 = Int32.Parse(txtExam2.Text);
std.Exam3 = Int32.Parse(txtExam3.Text);
std.FinalExam = Int32.Parse(txtFinal.Text);
stu.addItem(std);
this.Hide();
}
}
}
and this is my main form it has listbox to display list of students
public class StudentForm : Form
{
public StudentForm()
{
InitializeComponent();
}
public List<Student> students = new List<Student>();
public void addItem(Student std)
{
students.Add(std);
// it always show me 1 item in list
MessageBox.Show(students.Count.ToString());
}
}
Here's how your code is progressing, with comments added and irrelevant code removed:
private void btnSubmit_Click(object sender, EventArgs e)
{
...
// create a _new_ Student form
Student std = new Student();
...
// Add the student form to itself (huh?)
std.addItem(std);
// hide this form
this.Hide();
// show the new form
std.Show();
}
So you are always showing a new form with one item - the one that was just created.
Yeah that's cause in your btnSubmit_Click every time you are creating a new instance of the form Student and calling the addItem() method.
You rather move this field to a separate class like
public class Data
{
private string _firstName;
private string _lastName;
private int _exam1;
private int _exam2;
private int _exam3;
private int _finalExam;
}
have the form instance created in the start up like
public partial class AddStudent : Form
{
Student stu = null;
public AddStudent()
{
InitializeComponent();
stu = new Student();
stu.Show();
}
Change the list in Form1
public List<Data> students = new List<Data>();
In button click just add the Data instance like
private void btnSubmit_Click(object sender, EventArgs e)
{
// split the name into first and last name
string[] name = txtName.Text.Split(',');
Data std = new Data();
std.FirstName = name[0];
std.LastName = name[1];
std.Exam1 = Int32.Parse(txtExam1.Text);
std.Exam2= Int32.Parse(txtExam2.Text);
std.Exam3 = Int32.Parse(txtExam3.Text);
std.FinalExam = Int32.Parse(txtFinal.Text);
stu.addItem(std);
this.Hide();
}
This is because you're creating the Student form each time using this line:
Student std = new Student();
So every time you're clicking submit, you're creating a new Student form which creates a new empty public List<Student>
You need to seperate your model (Student) from your UI (StudentForm) and (AddStudentForm):
public class Student
{
public string FirstName { set; get; }
private string LastName { set; get; }
private int Exam1 { set; get; }
private int Exam2 { set; get; }
private int Exam3 { set; get; }
private int FinalExam { set; get; }
}
You don't need to create a new StudentForm each time you add a Student. Instead, you can have one StudentForm and use ShowDialog() when navigating to the Addition Screen, this you go back to the same instance of StudentForm.
Try removing the Class Student instantiation out of the event - btnSubmit_Click event
Student std = new Student();

Why are the values not showing up in my C# program's read-only labels?

I have been working on a program that requires two class definitions (clsCustomer and clsOrder) and a driver that is used for simulating an order form that calculates totals and prints a mailing label. The instructor provided partial code and I got rid of the previous errors that it had, but when I run the program and enter the information (name, address, quantity, price, etc.) only a "." shows up as the mailing label and both the extension and total price appear as "0.00". I tried playing with it and cannot seem to fix the issue. Here is the code:
namespace CS8
{
public partial class frmCS8 : Form
{
public frmCS8()
{
InitializeComponent();
}
private void btnCalculate_Click(object sender, EventArgs e)
{
string strMailingLabel;
try
{
//Create an instance of clsCustomer using the overloaded constructor
clsCustomer cobjCustomer = new clsCustomer(txtName.Text, txtStreet.Text,
txtCity.Text, txtState.Text, txtZip.Text);
//Build mailing label using the Get methods for Customer.
strMailingLabel = cobjCustomer.Name + "\n" +
cobjCustomer.Street + "\n" +
cobjCustomer.City + ", " +
cobjCustomer.State + " " + cobjCustomer.Zip;
//Display mailing address
lblMailingLabel.Text = strMailingLabel;
//Create an instance of clsOrder using the overloaded constructor
clsOrder cobjOrder = new clsOrder
(txtDescription.Text,
int.Parse(txtQuantity.Text),
decimal.Parse(txtPrice.Text));
//Test the calculate Extended Price method
cobjOrder.calcExtendedPrice();
//Update the totals in shared variables.
cobjOrder.accumulateTotals();
//Test the Get property method of extended priced
lblExtension.Text = cobjOrder.ExtendedPrice.ToString("C");
//Shared properties are accessed using class name
//Test the Get Property methods of ReadOnly Shared properties
lblTotalCount.Text = clsOrder.TotalCount.ToString("N0");
lblTotalPrice.Text = clsOrder.TotalPrice.ToString("C");
}
catch (Exception ex)
{
MessageBox.Show("Error :" + ex.Message
+ "\n" + ex.StackTrace,
"Try/Catch - Unexpected Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}//end try
}
private void btnNextItem_Click(object sender, EventArgs e)
{
//clear the item fields
txtDescription.Clear();
txtQuantity.Clear();
txtPrice.Clear();
lblExtension.Text = "";
txtDescription.Focus();
}
private void btnResetSummary_Click(object sender, EventArgs e)
{
//Reset totals using the class name to access the shared method
clsOrder.resetTotals();
lblTotalPrice.Text = "";
lblTotalCount.Text = "";
lblMailingLabel.Text = "";
//Clear the rest of the form using next item method
btnNextItem_Click(sender, e);
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
namespace CS8
{
public class clsOrder
{
//declare class variables
protected string cstrDescription;
protected int cintQuantity;
protected decimal cdecPrice;
protected decimal cdecExtendedPrice;
//shared variables
static decimal cdecTotalPrice;
static int cintTotalCount;
//declare constructors
public clsOrder()
{
}
public clsOrder(string strDescription,
int intQuantity, decimal decPrice)
//declare property methods
{
this.Description = cstrDescription;
this.Quantity = cintQuantity;
this.Price = cdecPrice;
}
//declare read-only properties
public decimal ExtendedPrice
{
get
{
return cdecExtendedPrice;
}
set
{
cdecExtendedPrice = value;
}
}
public string Description
{
get
{
return cstrDescription;
}
set
{
cstrDescription = value;
}
}
public int Quantity
{
get
{
return cintQuantity;
}
set
{
cintQuantity = value;
}
}
public decimal Price
{
get
{
return cdecPrice;
}
set
{
cdecPrice = value;
}
}
//declare Shared (static) ReadOnly Properites
public static decimal TotalPrice
{
get
{
return cdecTotalPrice;
}
}
public static int TotalCount
{
get
{
return cintTotalCount;
}
set
{
cintTotalCount = value;
}
}
//declare supporting methods
public void calcExtendedPrice()
{
cdecExtendedPrice = cintQuantity * cdecPrice;
}
public void accumulateTotals()
{
cdecTotalPrice += cdecExtendedPrice;
cintTotalCount += 1;
}
public static void resetTotals()
{
cdecTotalPrice = 0;
cintTotalCount = 0;
}
}//end of Class
}//end of namespace
namespace CS8
{
public class clsCustomer
{
//declare class variables
private string cstrName;
private string cstrStreet;
private string cstrCity;
private string cstrState;
private string cstrZip;
//declare constructors
public clsCustomer()
{
}
public clsCustomer(string strName,
string strStreet, string strCity,
string strState, string strZip)
{
this.Name = cstrName;
this.Street = cstrStreet;
this.City = cstrCity;
this.State = cstrState;
this.Zip = cstrZip;
}
public string Name
{
get
{
return cstrName;
}
set
{
cstrName = value;
}
}
public string Street
{
get
{
return cstrStreet;
}
set
{
cstrStreet = value;
}
}
public string City
{
get
{
return cstrCity;
}
set
{
cstrCity = value;
}
}
public string State
{
get
{
return cstrState;
}
set
{
cstrState = value;
}
}
public string Zip
{
get
{
return cstrZip;
}
set
{
cstrZip = value;
}
}
}
}
Any assistance would be very much appreciated...
Use parameters, not class fields:
public clsOrder(string strDescription,
int intQuantity, decimal decPrice)
{
this.Description = strDescription;
this.Quantity = intQuantity;
this.Price = decPrice;
}
public clsCustomer(string strName,
string strStreet, string strCity,
string strState, string strZip)
{
this.Name = strName;
this.Street = strStreet;
this.City = strCity;
this.State = strState;
this.Zip = strZip;
}

C# Communication between parent form and child form

My project has two classes. The first class has information about continents and it contains also a list of objects of countries (another class).
I also declared a list of continents that contains all the continents.
I've succeeded in filling the list from a file, and succeeded to show them in a DataGridView in the same form. But the problem is that I didn't find a way to show them in a child form that contains a DataGridView.
So, how can I transfer the list of continents to the child form so that I can be able to show them in it?
I tried serialiization and deserialization, but it didn't work, I just see the name of members of continent class and nothing else.
Here are the two class and code of toolstrip that show the child form:
// first class of continent
namespace WindowsFormsApplication1
{
[Serializable]
class continent
{
//champs
private string nomc;
public string Nomc
{
get { return this.nomc; }
}
private string sup;//SUP
public string Superficie
{
get { return this.sup; }
set { this.sup = value; }
}
private string pop;//POP
public string Population
{
get { return this.pop; }
set { this.pop = value; }
}
private string dens;//DENS :
public string Densité
{
get { return this.dens; }
set { this.dens = value; }
}
private string nbp;//NBP : 54 :
public string nombre_de_Pays
{
get { return this.nbp; }
set { this.nbp = value; }
}
private string fus;//FUS )
public string Fuseaux_horaires
{
get { return this.fus; }
set { this.fus = value; }
}
private string pnb;//PNB
public string PNB_habitant
{
get { return this.pnb; }
set { this.pnb = value; }
}
//constructeur
public continent(string nom)
{
this.nomc = nom;
}
public continent()
{
// TODO: Complete member initialization
}
//list of countries of that continent
public List<country> listep = new List<country>();
}
// class of countries
namespace WindowsFormsApplication1
{
[Serializable]
class country
{
//champs
private string nom_p;
public string Nom_pays
{
get { return this.nom_p; }
set { this.nom_p = value; }
}
private string cap;//PCAP
public string Capitale
{
get { return this.cap; }
set { this.cap = value; }
}
private string sup;// PSUP
public string Superficie
{
get { return this.sup; }
set { this.sup = value; }
}
private string reg;// REG
public string Régime_politique
{
get { return this.reg; }
set { this.reg = value; }
}
private string dev;//PDEV nationale
public string Devise
{
get { return this.dev; }
set { this.dev = value; }
}
private string hym;// PHYM
public string Hymne
{
get { return this.hym; }
set { this.hym = value; }
}
private string lg;// PLG
public string Langue
{
get { return this.lg; }
set { this.lg = value; }
}
private string mo;// PMO
public string Monnaie
{
get { return this.mo; }
set { this.mo = value; }
}
private string de;
public string PDE
{
get { return this.de; }
set { this.de = value; }
}
//constructeur
public country (string nom)
{
this.nom_p = nom;
}
}
}
and the code in the form is
//liste of contnents
List<continent> listec = new List<continent>();
// i filled it from a file
//here the code of toolstrip that open the childform
private void listeContinentToolStripMenuItem_Click(object sender, EventArgs e)
{
listecont flc = new listecont();
flc.ShowDialog();
flc.MdiParent = this;
}
In your child form, add an overload to the Form constructor that takes a Form as an argument. Then when you create your child form, you can pass in an instance of your current (parent) form like, listecont flc = new listecont(this); where this is a reference of your parent form. Now your child form can make calls to parentForm.Textbox.Text = "blablabal" or what ever object you want to interact with.
Why not just add a constructor to the listecont class that takes a List<continent>? Then, the child form will have the data when it's constructed.
in your MDI child add a method:
public void SetContinentData(List<continent> list)
{
// add your DataSource to the grid
// f.e.:
dataGridView.DataSource = list;
}
and in your Toolstrip handler:
private void listeContinentToolStripMenuItem_Click(object sender, EventArgs e)
{
listecont flc = new listecont();
flc.SetContinentData(listec);
flc.ShowDialog();
flc.MdiParent = this;
}

Inserting a list into a listbox in C#

I have made a list and the data is added into the list by the user using textboxes and comboboxes, I am now trying to enter this list of data into a listbox but everytime I try to add the data I get the output as the class name e.g WindowApplicaion.Journey or it comes out as System.Collections.Generic.List`1[WindowApplication.Journey], i'm not sure if this is due to me placing the conversion code in the wrong place or i'm just doing it all wrong, here is my code for both cases:
private void ShowAllToursbttn_Click(object sender, RoutedEventArgs e)
{
foreach (Tour t in company.tours)
{
string converter = company.tours.ToString();
ToursListBox.Items.Add(converter);
}
}
or
private void ShowAllToursbttn_Click(object sender, RoutedEventArgs e)
{
foreach (Tour t in company.tours)
{
string ConvertedList = string.Join(" ", company.tours);
TourListBox.Items.Add(ConvertedList);
}
}
Where tours is my list I created in my company class and t is each instance in the list, any advice would be great, thank you!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WindowApplication
{
class Tour
{
private string custFirstname;
private string custSurname;
private string custAddress;
private string pickupArea;
private string pickupDateandTime;
private string pickupDescription;
private string destinationArea;
private string destinationDescription;
//Creating getters and setters for each attribute
#region getters/setters
public string firstname
{
get { return custFirstname; }
set { custFirstname = value; }
}
public string surname
{
get { return custSurname; }
set { custSurname = value; }
}
public string address
{
get { return custAddress; }
set { custAddress = value; }
}
public string pickuparea
{
get { return pickupArea; }
set { pickupArea = value; }
}
public string pickupdateandtime
{
get { return pickupDateandTime; }
set { pickupDateandTime = value; }
}
public string pickupescription
{
get { return pickupDescription; }
set { pickupDescription = value; }
}
public string destinationarea
{
get { return destinationArea; }
set { destinationArea = value; }
}
public string destinationdescription
{
get { return destinationDescription; }
set { destinationDescription = value; }
}
}
}
That is my Tour class.
private void AddThisTourbttn_Click(object sender, RoutedEventArgs e)
{
Tour t = new Tour();
t.firstname = CustomerFirstnameTxt.Text;
t.surname = CustomerSurnameTxt1.Text;
t.address = CustomerAddressTxt.Text;
t.pickupdateandtime = TourDateTimeTxt.Text;
t.pickuparea = TourPickupArea.Text;
t.pickupescription = TourPickupDescriptionTxt.Text;
t.destinationarea = TourDestinationArea.Text;
t.destinationdescription = TourDestinationDescriptionTxt.Text;
company.addTour(t);
}
and on my MainWindow I have assigned each textbox to its appropriate get/set.
Your program displaying class name in listbox because you use default object's toString() method in ShowAllToursbttn_Click, which will output class name. Try to override ToString() method in Tour class, to output string with your desired format for example:
public override string ToString()
{
return String.Format("Firstname: {0}; Surname: {1}", firstname, surname);
}
And change ShowAllToursbttn_Click logic to:
private void ShowAllToursbttn_Click(object sender, RoutedEventArgs e)
{
foreach (Tour t in company.tours)
{
TourListBox.Items.Add(t.ToString());
}
}

Categories