How do I create new class objects when clicking a button? - c#

I'll give you an example of what I want to see, but I can't do it in any way:
public class User
{
private string name;
private int age;
private int id;
public User(string name, int age, int id)
{
this.name = name;
this.age = age;
this.id = id;
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string name = tb1.Text;
int age = Convert.ToInt32(tb2.Text);
int id = Convert.ToInt32(tb3.Text);
User ??? = new User(name,age,id);
}
??? - what should I put in the name? After all, I need to create a new object each time, respectively, with different names. How to do it?

You best create a list (List<User>) (or other type of collection) to which you can add new elements:
private readonly List<User> users = new List<User>();
private void Button_Click(object sender, RoutedEventArgs e)
{
string name = tb1.Text;
int age = Convert.ToInt32(tb2.Text);
int id = Convert.ToInt32(tb3.Text);
users.Add(new User(name,age,id));
}
This list could be defined the class containing Button_Click() or somewhere else depending on what needs to be done with the created User instances.
Access of the List elements:
To then get the third user creaded, use
user someUser = users[2];
To get the first John in the users list, use
user john = users.First(x => x.name != "John");
To get all Johns, use
List<user> johns = users.Where(x => x.name != "John");

Related

How to use user_id from a label in another form

I am trying to create a function GetUserID() which returns the userID, which I have inserted into a label so I can use it in other forms.
But when I try to convert the label to int32 the label always seems to be empty. I think its because of where the function is placed in my code.
See:
private void Loginbtn_Click(object sender, EventArgs e)
{
var LoginFunction = new LoginFunction();
var DataTable = new DataTable();
DataTable = LoginFunction.Login(Usernametxt.Text.Trim(), Passwordtxt.Text.Trim());
int UserID = Convert.ToInt32(DataTable.Rows[0]["USER_ID"]);
if (DataTable.Rows.Count == 1)
{
CalculatorMain calculatorMain = new CalculatorMain();
MainMenu mainMenu = new MainMenu();
UserIDlbl.Text = Convert.ToString(UserID);
MessageBox.Show("ID = " + UserID);
this.Hide();
mainMenu.Show();
}
else
{
MessageBox.Show("You entered the wrong username or password");
}
}
public int GetUserID()
{
int UserID;
if (Int32.TryParse(UserIDlbl.Text, out UserID))
{
UserID = Convert.ToInt32(UserIDlbl.Text);
}
else
{
MessageBox.Show("Error, Label for UserID could not be parsed");
}
return UserID;
}
I'm not sure where else I can put this function to get it to work.
Here is the code to call the function which is used in a separate form.
private void WorkoutHistoryForm_Load(object sender, EventArgs e)
{
Login login = new Login();
int UserId = login.GetUserID();
this.sETSTableAdapter.Fill(this.gymDataSet.SETS, UserId);
}
I keep thinking there must be a better way to do this instead of storing the UserID in a label but I'm not sure how.
I would create a public class with a public field to store the UserID.
For example. let's say you have the UserID in an int variable as you have described. Now let's say you have created a public static class called Common defined with a public static field of type int called ID.
You can now store the UserID in the static field of the class:
Common.ID = UserID
Later, when you want to access the UserID from some other form, just do this:
string UserID = Common.ID
Easy peasey.
Of course, you don't need to do this in a separate class... your form itself is a class, and you can create your public field there, and call it like
Form1.UserID
Or whatever the name of your original form is where you captured the UserID...

How to Output from Generic Array List, to Listbox?

I am trying to output from Array list to a Listbox. My problem is I think is I do not know how to connect the Class to the Generic array list a made? The end result should look like this:
And the information should be then sorted like so: all the information enters the first list box, and then the above 18 goes to adults, and the below 18 to kids. My class looks like this:
namespace Patients
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public String Password { get; set; }
public Person() //Constructor
{
Age = 0;
Password = "";
}
public Person (string name, int age, string password) //Parameters
{
this.Name = name;
this.Age = age;
this.Password = password;
}
public override string ToString() //
{
return Name + Age.ToString() + Password; //outputs as a string
// return Name + " (" + Age + " years) " + Password ;
}
}
}
namespace Patients
{
public partial class WebForm1 : System.Web.UI.Page
{
public static void Page_Load(object sender, EventArgs e)
{
}
public void ButtonAdd_Click(object sender, EventArgs e)
{
Person p = new Person();
List<string> People = new List<string>();
People.Add(TextBoxName.Text);
People.Add(TextBoxAge.Text);
People.Add(TextBoxPassword.Text);
foreach (object Person in People)
{
ListBoxAll.Items.Add(p.Name + p.Age.ToString() + p.Password);
}
if (p.Age > 18)
{
ListBoxAdults.Items.Add(p.Name + p.Age.ToString() + p.Password);
}
else
{
ListBoxKids.Items.Add(p.Name + p.Age.ToString() + p.Password);
}
}
}
}
I think your problem is, that you don't set the Properties. In Fact you don't need a List at all, but you can use a List to keep hold of your patients. It's still not necessary though:
namespace Patients
{
public partial class WebForm1 : System.Web.UI.Page
{
// Define Property and initialize List
public List<Person> patients{ get; } = new List<Person>();
public static void Page_Load(object sender, EventArgs e)
{
}
public void ButtonAdd_Click(object sender, EventArgs e)
{
// Use the Constructor with Parameters
Person p = new Person(TextBoxName.Text, TextBoxAge.Text, TextBoxPassword.Text);
// Add your patient to your List
patients.Add(p);
// Use the ToString() of your Person
ListBoxAll.Items.Add(p.ToString());
if (p.Age > 18)
{
ListBoxAdults.Items.Add(p.ToString());
}
else
{
ListBoxKids.Items.Add(p.ToString());
}
}
}
}
Looks like you are mixing and matching a bit.
Try something like this.
Person p = new Person();
p.Name = TextBoxName.Text;
p.Age= TextBoxAge.Text;
p.Password= TextBoxPassword.Text;
ListBoxAll.Items.Add(p);
A few tricks that are nice to us, first off you can declare defaults for properties like so:
public string Name { get; set; } = "Steve";
public int Age { get; set; } = 1;
public String Password { get; set; } = "password";
However, it should also be noted that "" is the default for strings already and 0 is the default for non-nullable int, so you don't even need to worrying about those default values.
Declaring Age = 0; in the constructor is basically a waste of time in this case. (If it was a nullable int however the default is null)
Next up, since you are okay with defaults, you don't need to declare properties in the constructor like you are.
You can completely remove the constructor and just do the following:
var myPerson = new Person { Name = "Steve", Age = 18, Password = "Foo" };
Next up, you are losing all your existing people as soon as you exit the scope of the button click.
Instead you'll want to declare two lists of people outside the scope of the click method (that way they persist), something like "Adults" and "Children"
Then perhaps make a method called "PopulateLists" that would do the following:
Clear all list boxes
Add to each box the list of each groups names that apply (you can make an IQueryable by using Linq and Select statements on your list)
When you click the button, you should make a new person, assign it to the right list, then call PopulateLists()
Here's the info you need to get started:
Linq selection to get list of properties (in this case Im going to turn a List of People into a List of Ages, you can do the same with names though)
var ages = People.Select(p => p.Age);
The .Items property of a ListBox works the same as a list, it just visually shows itself. It's a list of strings specifically.
So for example you can do things like...
MyListBox.Items.Clear();
MyListBox.Items.Add(...);
MyListBox.Items.AddRange(...);
etc etc.
That should get you started!

C# - How to use Dictionaries with GUI

I'm struggling to understand how a user can add a value to a dictionary with the use of a GUI.
I've managed to do this with the use of a list:
List<Person> clients = new List<Person>();
Person x = new Person();
x.Name = nameTextbox.text;
x.Address = addressTextbox.Text;
clients.Add(x);
public void AddClientButton_Click(object sender, EventArgs e)
{
Class Person{
public string Name{
get {return Name}
value { name = value;}
public string Address{
get {return Address}
value { name = Address;}
}
}
I've just typed this out as I'm not on my Windows machine (so forgive me so any mistakes), but none-the-less it works. However, I'm required to use a Dictionary due to the fact it has a Key & Value.
Everyone seems to add the data themselves and within a ConsoleApplication, I'm required to let the User add the data with the use of a GUI. I was wondering if the concept is similar with the use of a Dictionary or are they worlds apart?
Dictionary<string, string> clients = new Dictionary<string, string();
Person x = new Person();
x.Name = nameTextbox.text;
x.Address = addressTextbox.Text;
clients.Add(x);
public void AddClientButton_Click(object sender, EventArgs e)
{
Class Person{
public string Name{
get {return Name}
value { name = value;}
public string Address{
get {return Address}
value { name = Address;}
}
}
Could someone please point me in the right direction, possibly with the use of an example so I can grasp the concept.
Thank you.
Assuming the name of the person is unique
Dictionary<string, Person> clients = new Dictionary<string, Person>();
....
public void AddClientButton_Click(object sender, EventArgs e)
{
Person x = new Person();
x.Name = nameTextbox.text;
x.Address = addressTextbox.Text;
clients.Add(x.Name, x); //Beware, if the name is not unique an exception will be thrown.
}

How can I share variables between Web forms?

I am developing a web application on C# .Net and I need to pass variables from form to another form. For example, in the first form I have person class as following;
public class Person
{
private string _Name;
private string _Surname;
private string _DateOfBirth;
private string _Gender;
private string _Symptoms;
public Person()
{
Name = "Not available";
Surname = "Not available";
DateOfBirth = "Not available";
Gender = "Not available";
Symptoms = "Not available";
}
public string Name
{
get { return _Name; }
set { _Name = value; }
}
public string Surname
{
get { return _Surname; }
set { _Surname = value; }
}
public string DateOfBirth
{
get { return _DateOfBirth; }
set { _DateOfBirth = value; }
}
public string Gender
{
get { return _Gender; }
set { _Gender = value; }
}
public string Symptoms
{
get { return _Symptoms; }
set { _Symptoms = value; }
}
}
Then I assign values;
protected void Page_Load(object sender, EventArgs e)
{
Person MyPerson = new Person();
MyPerson.Name = txtName.Text;
MyPerson.Surname = txtSurname.Text;
MyPerson.DateOfBirth = txtBirth.Text;
MyPerson.Gender = listGender.Text;
MyPerson.Symptoms = checked(listSymptoms.Text);
}
So, how can I use these values into another form?
consider Another_form is a new form's class that contain a method should accept an object(person class)... for example
public void foo(Person obj)
{ ///your code }
that's it... then you have to pass variable from another form like
protected void Page_Load(object sender, EventArgs e)
{
Person MyPerson = new Person();
MyPerson.Name = txtName.Text;
MyPerson.Surname = txtSurname.Text;
MyPerson.DateOfBirth = txtBirth.Text;
MyPerson.Gender = listGender.Text;
MyPerson.Symptoms = checked(listSymptoms.Text);
another_form f=new another_form();
f.foo(MyPersion)
}
You could make your form produce a Person instance instead:
// within your form class, whatever it is
public Person CreatePerson()
{
Person MyPerson = new Person();
MyPerson.Name = txtName.Text;
MyPerson.Surname = txtSurname.Text;
MyPerson.DateOfBirth = txtBirth.Text;
MyPerson.Gender = listGender.Text;
MyPerson.Symptoms = checked(listSymptoms.Text);
return MyPerson;
}
Then, from anywhere in your code, call your form instance's CreatePerson method:
var personFromUI = yourFormInstance.CreatePerson();
That is one way to do it.
You could also expose the person as a property of your form, or pass a Person instance throughout your application objects, be it forms, controls, controllers, etc... while this goes beyond the scope of your question, this would be the preferred way because it keeps your UI code and your business code separated.
I'd advise that you look into separation of concerns. You may learn a trick or two there about proper application design.
Are you saying that you have populated a person object and then on another form you'd like to reference the same instance of that person object? Probably the simplest way would be to store the object in Session and then retrieve it on the second form.
protected void Page_Load(object sender, EventArgs e)
{
Person MyPerson = new Person();
MyPerson.Name = txtName.Text;
MyPerson.Surname = txtSurname.Text;
MyPerson.DateOfBirth = txtBirth.Text;
MyPerson.Gender = listGender.Text;
MyPerson.Symptoms = checked(listSymptoms.Text);
Session["CurrentPerson"] = MyPerson;
}
Personally, I don't normally use session this way and instead build that type of workflow into my apps persistence layer (e.g. Sql Server, Redis).

Comparing two object state,before and after update

first things first.
I have the following classes:
class Employee
{
private int employeeID;
private string firstName;
private string lastName;
private bool eligibleOT;
private int positionID;
private string positionName;
private ArrayList arrPhone;
public IList<Sector> ArrSector {get; private set;}
//the constructor method takes in all the information of the employee
public Employee(int empID, string fname, string lname, bool elOT, int pos, string posname)
{
employeeID = empID;
firstName = fname;
lastName = lname;
eligibleOT = elOT;
positionID = pos;
positionName = posname;
arrPhone = new ArrayList();
ArrSector = new List<Sector>();
}
//the constructor method takes in the employee id, the first name and the last name of the employee
public Employee(int empid, string firstname,string lastname)
{
employeeID = empid;
firstName = firstname;
lastName = lastname;
}
//overtides the first name and the last name as a string.
public override string ToString()
{
return firstName +" "+lastName;
}
public int EmployeeID
{
get { return employeeID; }
set { employeeID = value; }
}
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
public bool EligibleOT
{
get { return eligibleOT; }
set { eligibleOT = value; }
}
public int PositionID
{
get { return positionID; }
set { positionID = value; }
}
public string PositionName
{
get { return positionName; }
set { positionName = value; }
}
public ArrayList ArrPhone
{
get { return arrPhone; }
set { arrPhone = value; }
}
// The function assigns all the variables associated to the employee to a new object.
public static object DeepClone(object obj)
{
object objResult = null;
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, obj);
ms.Position = 0;
objResult = bf.Deserialize(ms);
}
return objResult;
}
//Memento pattern is used to save the employee state.
//The changes will be rolled back if the update button not clicked
public class Memento : IMemento
{
private Employee originator = null;
private int employeeID;
private string firstName;
private string lastName;
private bool eligibleOT;
private int positionID;
private string positionName;
private ArrayList arrPhone;
private IList<Sector> arrSector;
public Memento(Employee data)
{
this.employeeID = data.EmployeeID;
this.firstName = data.FirstName;
this.lastName = data.LastName;
this.eligibleOT = data.EligibleOT;
this.positionID = data.PositionID;
this.positionName = data.PositionName;
this.arrPhone = data.ArrPhone;
this.originator = data;
this.arrSector = Extensions.Clone<Sector>(data.ArrSector);
}
}
I am using C sharp in winforms. the front end of my application has a listbox on the left end side which has the first name of the employee.on the left hand side, there are different textboxes which correspond to the employee selected in the list box. I have coded it in such a way that everytime i select an employee, its attributes, like the employee id, name, position, etc are displayed in these fields.
if the user changes any attribute of the employee, he has to click an update button to make the changes to the database.
now the real problem, when the user changes any field of the selected employee, and selects another employee without clicking the update button, i want to show a pop up box to tell the user that if he selects another employee , all the changes will be lost.
for this reason i have created the momento class to hold the previous state of the employee.
i have also tried overloading the == operator
public static bool operator ==(Employee e, Memento m)
{
return ((e.employeeID == m.employeeID) &&
(e.firstName == m.firstName) &&
e.lastName == m.lastName &&
e.eligibleOT == m.eligibleOT &&
e.positionID == m.positionID &&
e.positionName == m.positionName &&
e.arrPhone == m.arrPhone &&
e.ArrSector == m.arrSector);
}
public static bool operator !=(Employee e, Memento m)
{
return (e.employeeID != m.employeeID);
}
my idea was to compare the two object...
but m not successfull. how do i do it??how do i show the popup if changes are made.?where do i place the code to show the popup?
One word of warning...it's generally not a good idea to have different logic in your == and != operators. It's somewhat unintuitive to be able to have both == and != be false at the same time.
if(!(a == b) && !(a != b))
{
// head explodes
}
That aside, I'm guessing that you have your Employee class referenced as an object (or other parent class) in your comparison code. Maybe something like this:
if(listBox1.SelectedItem != currentMemento)
{
...
}
If this is the case, then the compiler isn't binding the != to your custom implementation. Cast listBox1.SelectedItem to Employee in order to force that.
if((Employee)listBox1.SelectedItem != currentMemento)
{
...
}
There are, however, many other approaches that you could take to solve this issue:
Make the implementation entirely on the GUI side, with a bool that gets set to true when the data in the text fields changes, then check that flag when changing employees
Implement the IComparable or IEquatable interfaces
Override the Equals method on the Employee and/or Memento class
(If you go with the second option, it's generally recommended that you complete the third as well)
Example
Here's an example of what you could do (I'm assuming you have a ListBox named listBox1 and you've attached to the SelectedIndexChanged event with the listBox1_SelectedIndexChanged function):
private Employee lastSelectedEmployee;
private Memento selectedMemento;
void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Employee selectedEmployee = (Employee)listBox1.SelectedItem;
if(lastSelectedEmployee != null && lastSelectedEmployee != selectedEmployee)
{
if(/*changes exist*/)
{
if(/*cancel changes*/)
{
listBox1.SelectedItem = lastSelectedEmployee;
return;
}
}
}
lastSelectedEmployee = selectedEmployee;
selectedMemento = //create the memento based on selectedEmployee;
}
You'll have to provide your own logic for the areas I've left comments, but the idea should be pretty straightforward.
Have a look at the IComparable interface. It requires you to implement the method you need t make such a comparison. KB article, Hopefully it turn English for you, on my PC it turns always German.
-sa

Categories