How do I set property to zero - c#

I need to set a label to zero. It is showing 120. There is a button that will return the required hours for this program. It is a program that returns the required hours for students major. There are 3 forms. bladah bladah yadah yadah. asdfkashdfjkhasjkdhfjkasdjkfajkdjfkajksdfjkakjshdfkjakjsdfjkashdfakjsdf
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Computer_Science_Student
{
class CompSciStudent : Student
{
// Constants
private double MATH_HOURS = 20;
private double CS_HOURS = 40;
private double GEN_HOURS = 60;
// Fields
private string _academicTrack;
// Constructor
public CompSciStudent(string name, string id, string track)
: base(name, id)
{
_academicTrack = track;
}
// AcademicTrack property
public string AcademicTrack
{
get { return _academicTrack; }
set { _academicTrack = value; }
}
// RequiredHours property
public override double RequiredHours
{
get { return MATH_HOURS + CS_HOURS + GEN_HOURS; }
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Computer_Science_Student
{
abstract class Student
{
// Fields
private string _name;
private string _id;
// Constructor
public Student(string name, string id)
{
_name = name;
_id = id;
}
// Name property
public string Name
{
get { return _name; }
set { _name = value; }
}
// ID property
public string ID
{
get { return _id; }
set { _id = value; }
}
// RequiredHours property (abstract)
public abstract double RequiredHours
{
get;
}
}
}
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 Computer_Science_Student
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// Variables to hold input
string name, id, track;
// Get the student's name and ID.
name = nameTextBox.Text;
id = idTextBox.Text;
// Get the student's academic track
if (infoSystemsRadioButton.Checked)
{
track = "Information Systems";
}
else
{
track = "Software Engineering";
}
// Create a CompSciStudent object.
CompSciStudent csStudent =
new CompSciStudent(name, id, track);
// Display the student's required hous.
requiredHoursLabel.Text =
csStudent.RequiredHours.ToString("n1");
}
private void ExitButton_Click(object sender, EventArgs e)
{
// Close the form
this.Close();
}
}
}

In your code class CompSciStudent has the following attributes and methods:
// Constants
private double MATH_HOURS = 20;
private double CS_HOURS = 40;
private double GEN_HOURS = 60;
public override double RequiredHours
{
get { return MATH_HOURS + CS_HOURS + GEN_HOURS; }
}
RequiredHours always returns sum of MATH_HOURS + CS_HOURS + GEN_HOURS, which equals 120.
Also as another person pointed out, those are not constants, they are variables. A constant would be:
const double MATH_HOURS = 20;
Here you're creating a new CompSciStudent object:
// Create a CompSciStudent object.
CompSciStudent csStudent = new CompSciStudent(name, id, track);
// Display the student's required hous.
requiredHoursLabel.Text = csStudent.RequiredHours.ToString("n1");
In your Form1_Load() method you're setting requiredHoursLabel.Text to csStudent.RequiredHours which is always 120 that's why you're seeing "120" in the text field.
The Form1_Load() method is going to be called after your form loads so it is typically used to initialize the form. So what you're doing right now is to initialize requiredHoursLabel.Text to 120.
If you have some other behavior in mind they you'll need to add something like another button besides "Close" like "OK" or "Save" or something to accept the input the user entered into the form.

Related

C# WPF How do you set up an "Update" button to change the contents of a row on a table?

I am new to WPF and I am trying to figure out how to create an "Update" button that will show all the contents of a row on a table, allowing the user to change any category and save the new data.
What the main window would look like :
Then when the update button is clicked, a window looking like this would pop up. :
How would you make the second window? Down below is what I have to show the main window without an "update" button.
**MainWindowxaml.cs**
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections;
using System.IO;
namespace Sort_a_list
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public class Student
{
public string name
{
get;
set;
}
public int age
{
get;
set;
}
public string gender
{
get;
set;
}
public string major
{
get;
set;
}
public string classification
{
get;
set;
}
}
public MainWindow()
{
InitializeComponent();
List<Student> user = new List<Student>();
try
{
using (StreamReader sr = new StreamReader(#"C:\Users\justi\Documents\2021 Self Study\WPF C#\Samples.txt"))
{
string line;
char[] sep = { ',' };
int length;
ArrayList rows = new ArrayList();
while ((line = sr.ReadLine()) != null)
{
string[] words = line.Split(sep);
length = words.Length;
rows.Add(words);
}
string[] columns;
for(int i = 1; i < rows.Count; i++)
{
columns = (string[])rows[i];
user.Add(new Student() { name = columns[0], age = Int16.Parse(columns[1]), gender = columns[2], major = columns[3], classification = columns[4] });
}
}
}
catch(Exception e)
{
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
sort.ItemsSource = user;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
}
}
}
Please help! Thank you very much!
You won't be able to access your Window1's DataGrid from Window2 directly.
You also not have access to your source collection (List) from Window2 to modify it from there.
In that facts, you got 2 ways:
use external database;
create public fixed collection of Students.
First of all and in any way I strongly recommend you to add some ID field to your Student object to be able unify each student.
If use external database, you can simply call something like "UPDATE students s SET s.name = #name, s.age = #age... WHERE s.ID = #id" from your Window2 when Save button clicked. #name, #age ... is new modified values
If use public fixed collection, you can access it from any part of your program.
When Window2 Save button clicked, you can search for student in it by student's ID and simply edit him. After Window2 closing you need just refresh DataGrid view by resetting ItemsSource.
It may look like this:
Student class:
public class Student
{
// Need to be unique for each student
public int ID { get; private set; }
public string Name { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
public string Major { get; set; }
public string Classification { get; set; }
public Student(int id)
{
ID = id;
Name = "SomeName";
Age = -1;
Gender = "Unknown";
Major = "Unknown";
Classification = "None";
}
// May also be overloaded with id, id+name, id+name+age, id+name+age+gender etc
public Student(int id, string name, int age, string gender, string major, string classification)
{
ID = id;
Name = name;
Age = age;
Gender = gender;
Major = major;
Classification = classification;
}
// If you need some kind of string representation of Student
public override string ToString()
{
return $"{ID},{Name},{Age},{Gender},{Major},{Classification}";
}
}
Fixed and public collection class to store Students:
public static class DB
{
// Your actual Database, where Students would be stored
private static readonly List<Student> students = new List<Student>();
// You can get it by DB.Students from anywhere
public static List<Student> Students { get { return students; } }
// As I see you use a file as source for item collection.
// You can add some Save() method to rewrite you existing
// file with items from "database":
// public static void Save()
// {
// StringBuilder sb = new StringBuilder();
//
// foreach (Student student in students)
// {
// sb.AppendLine(student.ToString());
// }
//
// File.WriteAllText("PathToYourFile", sb.ToString());
// }
//
// You should also override ToString method in Student class
// with something like (in format you wish):
// public override string ToString()
// {
// return $"{ID},{Name},{Age},{Gender},{Major},{Classification}";
// }
}
}
Update button click handler at Window1:
private void ButtonUpdate_Click(object sender, RoutedEventArgs e)
{
// There should be selected only 1 item or use dataGrid.SelectedItems[0]
if (dataGrid.SelectedItem is Student student)
{
// Pass selected Student to Window2
// where user will edit it
Window2 w2 = new Window2(student);
// Subscribe to Closed window to refresh DataGrid view after Student editing
w2.Closed += (s, a) =>
{
// Refresh the view of DataGrid by resetting its ItemsSource property
dataGrid.ItemsSource = null;
dataGrid.ItemsSource = DB.Students;
};
// Show update window
w2.ShowDialog();
}
}
And some kind of Window2:
public partial class Window2 : Window
{
// Here would be a copy of Student object from Window1
// with which we would manipulate in Window2
// while editing in its fields
private readonly Student editableStudent = null;
public Window2(Student student)
{
InitializeComponent();
// Copy student object to store it in our Window2
// and be able to modify it not only from Constructor
editableStudent = student;
// Fill Window2 fields with existing Student values
tbName.Text = student.Name;
tbAge.Text = student.Age.ToString();
tbGender.Text = student.Gender;
tbMajor.Text = student.Major;
tbClassification.Text = student.Classification;
// Easy "on-the-fly" subscribe to each field TextChanged handlers to check,
// whether some data was changed/edited or not
// and save it to editableStudent
tbName.TextChanged += (s, a) =>
{
// Comparing value in field with existing Student's value
if (tbName.Text != student.Name) // May also check for not empty / or for min input length
{
// Saving new value to a copied object of our Student
editableStudent.Name = tbName.Text;
}
};
// Don't forget to check for integer value
// and convert in back to int:
// Convert.ToInt32(tbAge.Text)/int.Parse(tbAge.Text)/int.TryParse(tbAge.Text, out int age)
tbAge.TextChanged += (sender, args) => { /* Do same as with Name */ };
tbGender.TextChanged += (sender, args) => { /* Do same as with Name. */ };
tbMajor.TextChanged += (sender, args) => { /* Do same as with Name */ };
tbClassification.TextChanged += (sender, args) => { /* Do same as with Name */ };
}
private void ButtonSave_Click(object sender, RoutedEventArgs e)
{
// Find index of Student element in our "Database" (List)
int index = DB.Students.FindIndex(x => x.ID == editableStudent.ID);
if (index != -1)
{
// Update record in a collection if it was found
DB.Students[index].Name = editableStudent.Name;
DB.Students[index].Age = editableStudent.Age;
DB.Students[index].Gender = editableStudent.Gender;
DB.Students[index].Major = editableStudent.Major;
DB.Students[index].Classification = editableStudent.Classification;
// Instead of use 'editableStudent' field with copied in
// constructor student's object, you can create it here
// and fill with values from TextBoxes in Window2.
// Or not create new Student object and fill new values
// directly in "database" by index.
// But you anyway need to store at least student's ID from
// student's object, passed from Window1, to be able to
// find him in "database"
// Student modifiedStudent = new Student(...);
// modifiedStudent.Name = tbName.Text;
// if (int.TryParse(tbAge.Text, out int age))
// modifiedStudent.Age = age;
// ...
// DB.Students[index].Name = modifiedStudent.Name;
// DB.Students[index].Age = modifiedStudent.Age;
// ...
// or
// DB.Students[index].Name = tbName.Text;
// if (int.TryParse(tbAge.Text, out int age))
// DB.Students[index].Age = age;
// ...
}
else
{
// Or message user if not found
MessageBox.Show("Student not found in Database (in a List of Students).");
}
// Close window after updating record in "Database"
// DataGrid view we will refresh from Window1 after
// Window2 close
Close();
}
private void ButtonCancel_Click(object sender, RoutedEventArgs e)
{
// Do nothing with Student, just close
Close();
}
}

C# Adressing multiple variables using a for()

I have this code:
cpMythic0.Text = Properties.Settings.Default.M0;
and let's say I have 31 cpMythic (string) variables all being named "cpMythic0, cpMythic1, cpMythic2 ... cpMythic30 and the same goes with some Properties Settings string variables called "M0,M1,M2...M30"
Instead of writing this:
cpMythic0.Text = Properties.Settings.Default.M0;
cpMythic1.Text = Properties.Settings.Default.M1;
I would like to use a for() function, with an i variable but I don't really know the syntax.
I would appreciate any help.
I'm not sure why you'd want to do this, but this is achievable using reflection.
Here is an example:
using System;
using System.Data;
using System.Linq;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Fill_Click(object sender, EventArgs e)
{
string propertyMatcher = "cpMythic";
var defaultSettings = new Properties.Settings.Default(); //Get instance of default settings
var settingProperties = defaultSettings.GetType().GetFields(); //Get default setting properties.
foreach (TextBox control in this.Controls.OfType<TextBox>().Where(c => c.Name.StartsWith("cpMythic"))) //Loop through controls, and filter
{
string settingPropertyName = "M" + control.Name.Substring(propertyMatcher.Length);
var settingProperty = settingProperties.FirstOrDefault(p => p.Name == settingPropertyName);
var value = settingProperty.GetValue(defaultSettings); //Get the value of the corresponding setting using reflection
control.Text = value.ToString(); //Set value
}
}
private static class Properties
{
public static class Settings
{
public class Default
{
public string M0 = "Default Value 0";
public string M1 = "Default Value 1";
public string M2 = "Default Value 2";
}
}
}
}
}

How do you populate a list with a structure at form load in C#

I'm just flat out lost. What I need to do is get the structure, specifically cookie name to populate the list box. Than when i click on the selected item it should change the data in the labels... there is more to it but this is where I am right now. Yes it's homework but I'm also in my 30's with a good job. I'm just trying to learn this stuff so I might be able to use it in my hobbies. So please only help no snark about "do your own homework."
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;
namespace Unit_8_Cookie_Scouts
{
struct CookieStruct
{
public string cookieName;
public decimal cookiePrice;
public int inventoryNum;
public decimal valueOfInventory;
}
public partial class CookeScouts : Form
{
//create a List as a field
private List<CookieStruct> cookieList = new List<CookieStruct>();
List<string> cookieName = new List<string>() { "Peppermint Flatties", "Chocolate Chippers", "Pecan Paradise", "Sugary Shortcake" };
List<decimal> cookiePrice = new List<decimal>() { 4.99m, 4.76m, 6.82m, 5.99m };
List<int> inventoryNum = new List<int>() { 8, 17, 9, 12 };
List<decimal> valueOfInventory = new List<decimal>() { 39.92m, 80.92m, 61.38m, 71.88m };
public CookeScouts()
{
InitializeComponent();
int Index = lstCookies.SelectedIndex;
//update values with index 0
tempInfo.cookieName = cookieName(0);
//create a temp structure object to add values too
CookieStruct tempInfo = new CookieStruct();
//add temp structure object to list at form level
tempInfo.cookieName = cookieName(Index).Text;
//add temp structure to list at form level
cookieList.Add(tempInfo);
for (int index = 0; index < cookieList.Count; index++)
{
lstCookies.Items.Add(index);
}
LoadListBox();
}
private void btnUpdate_Click(object sender, EventArgs e)
{
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////// METHODS /////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void LoadListBox()
{
string output;
//loop through and add to combo box
foreach (CookieStruct tempInfo in cookieList)
{
//make output line for combo box
output = tempInfo.cookieName;
//send the output to combo box cboCustomers
lstCookies.Items.Add(output);
}
}
}
}
//////////////////////////////CLASS//////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Unit_8_Cookie_Scouts
{
class clsCookies
{
//delcare variables
string _ItemType;
decimal _Price;
decimal _Inventory;
decimal _Value;
//new instance of class
public clsCookies()
{
_ItemType = "";
_Price = 0;
_Inventory = 0;
_Value = 0;
}
public clsCookies(string CookieName, decimal CookiePrice, decimal InvAmount, decimal TotalValue)
{
_ItemType = CookieName;
_Price = CookiePrice;
_Inventory = InvAmount;
_Value = TotalValue;
}
//properties
public string CookieType
{
get { return _ItemType; }
set { _ItemType = value; }
}
public decimal Price
{
get { return _Price; }
set { _Price = value; }
}
public decimal Inventory
{
get { return _Inventory; }
set { _Inventory = value; }
}
public decimal Value
{
get
{
return _Value;
}
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// METHODS ///////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
public void UpdateInventory(int InvChanged)
{
_Inventory += InvChanged;
}
public void UpdateValue(decimal ValueChanged)
{
_Value = _Price * _Inventory;
}
}
}
Have a look at the answer, should help you..
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;
namespace Unit_8_Cookie_Scouts
{
struct CookieStruct
{
public string cookieName;
public decimal cookiePrice;
public int inventoryNum;
public decimal valueOfInventory;
}
public partial class CookeScouts : Form
{
//create a List as a field
private List<CookieStruct> cookieList = new List<CookieStruct>();
public CookeScouts()
{
InitializeComponent();
cookieList.Add(new CookieStruct() { cookieName = "Peppermint Flatties", cookiePrice = 4.99m, inventoryNum = 8, valueOfInventory = 39.92m });
cookieList.Add(new CookieStruct() { cookieName = "Chocolate Chippers", cookiePrice = 4.76m, inventoryNum = 17, valueOfInventory = 80.92m });
cookieList.Add(new CookieStruct() { cookieName = "Pecan Paradise", cookiePrice = 6.82m, inventoryNum = 9, valueOfInventory = 61.38m });
cookieList.Add(new CookieStruct() { cookieName = "Sugary Shortcake", cookiePrice = 5.99m, inventoryNum = 12, valueOfInventory = 71.88m });
LoadListBox();
}
private void btnUpdate_Click(object sender, EventArgs e)
{
int Index = lstCookies.SelectedIndex;
//update values with index 0
tempInfo.cookieName = cookieList[Index].cookieName;
//create a temp structure object to add values too
}
private void LoadListBox()
{
string output;
//loop through and add to combo box
foreach (CookieStruct tempInfo in cookieList)
{
//make output line for combo box
output = tempInfo.cookieName;
//send the output to combo box cboCustomers
lstCookies.Items.Add(output);
}
}
}
}

Validation of value in XML File

I'm trying to validate a username check box to see if the value entered exists in an XML file.
On button click, it should check if the name entered exists within the XML file and then proceed, if not the message box should appear.
The current code shows that the txt_Username.Text = Pupil.forename is inaccessible due to its protection level.
On button click:
private void btnNext_Click(object sender, RoutedEventArgs e, Pupil p)
{
if (txt_Username.Text = Pupil.forename)
{
this.Hide();
Display nw = new Display(theClass);
nw.ShowDialog();
this.Show();
}
MessageBox.Show("Cannot Find username");
}
Pupil Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PassingData
{
public class Pupil
{
private string forename;
private int score;
public Pupil(string forename, int score)
{
this.forename = forename;
this.score = score;
}
public Pupil()
{
this.forename = "Unknown";
}
public string Forename
{
get { return forename; }
set { forename = value; }
}
public int Score
{
get { return score; }
set { score = value; }
}
override public string ToString()
{
string output = forename + "\t" + score;
return output;
}
}
}
XML File:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfPupil xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Pupil>
<Forename>Andy</Forename>
<Score>0</Score>
</Pupil>
<Pupil>
<Forename>Bob</Forename>
<Score>10</Score>
</Pupil>
<Pupil>
<Forename>Carl</Forename>
<Score>20</Score>
</Pupil>
<Pupil>
<Forename>Dave</Forename>
<Score>30</Score>
</Pupil>
<Pupil>
<Forename>Eric</Forename>
<Score>40</Score>
</Pupil>
<Pupil>
<Forename>Frank</Forename>
<Score>50</Score>
</Pupil>
</ArrayOfPupil>
'forename' is a private variable
Pupil is not a Static Class
You need to create an instance of Pupil and use Forename property instead.
i.e
Pupil.Forename is NOT Allowed on a non-static class.
Instead
Pupil objPupil = new Pupil();
var myForeName = objPupil.Forename;
In your If statement there is only one =.
Default Button click handler/delegate cannot have the extra parameter Pupil p.
You are referencing "forename" (a private field) but should be referencing "Forename" (a public property).
You are referencing "Pupil.forename" but should be referencing "p.Forename".
As #MattMeadows mentioned, "==" should be used when checking for equality, not "=".
I also recommend auto properties for just setting and getting values: http://msdn.microsoft.com/en-us/library/bb384054.aspx.
Ex:
public string Forename { get; set; }

Checking To Make Sure My Object isn't Partially Initialized

I'm creating a simple application that takes a URL and a String and create the code for a hyperlink.
Here is my HyperLink Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LinkIt_
{
class HyperLink
{
private string url;
private string text;
public HyperLink()
{
}
public HyperLink(string url,string text)
{
this.Website = url;
this.Text = text;
}
public String Website
{
get
{
return url;
}
set
{
if (String.IsNullOrEmpty(value))
{
throw new ArgumentNullException("Must have URL!");
}
this.url = value;
}
}
public String Text
{
get
{
return text;
}
set
{
if (String.IsNullOrEmpty(value))
{
throw new ArgumentNullException("Must have Text!");
}
this.text = value;
}
}
public string addPoint()
{
return String.Format("<li>", url) + text + "</li>";
}
public override string ToString()
{
return String.Format("",url) + text + "" ;
}
}
}
Here is my Form Class
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 LinkIt_
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
HyperLink link;
try
{
if (chkPoint.Checked)
{
txtDisplay.Text = "";
link = new HyperLink(txtLink.Text, txtText.Text);
txtDisplay.Text = link.addPoint();
}
else
{
txtDisplay.Text = "";
link = new HyperLink(txtLink.Text, txtText.Text);
txtDisplay.Text = link.ToString();
}
}
catch (ArgumentNullException msg)
{
MessageBox.Show(msg.Message);
}
}
private void btnClear_Click(object sender, EventArgs e)
{
txtDisplay.Text = "";
txtLink.Text = "";
txtText.Text = "";
}
}
}
My Question:
How do I make sure that I don't create a partially initialized object?
If my code need correcting, Could someone help me ?
You could refactor your code to use properties with decreased accessor visibility.
This way the HyperLink objects can not be altered from outside the class (this is often a preferable attribute for data structures).
For example you could do something like this:
class HyperLink
{
public String Website{get; private set;}
public String Text {get; private set;}
public HyperLink(string url,string text)
{
if(string.isNullOrEmpty(url) || string.IsNullOrEmpty(text))
throw new ArgumentNullException("no partially intialized object allowed");
this.Website = url;
this.Text = text;
}
public string AddPoint()
{
return String.Format("<li>", url) + text + "</li>";
}
public override string ToString()
{
return String.Format("",url) + text + "" ;
}
}
Update to answer question in comments
Yes, it is perfectly reasonable to use the Getter/Setter from within the same object or class.
However, I advise to improve your usage of String.Format to the following:
String.Format("{1}",this.Link, this.Text);

Categories

Resources