I'm trying to learn List<> in C#. I made a test program that takes the result of three textboxes and inputs it in a multiline textbox, after I put them in a list (to later save the list to file).
Here is my class declaration:
public class Film
{
public Film (string Num, string Title, string Categ)
{
this.Numero = Num;
this.Titre = Title;
this.Categorie = Categ;
}
public string Numero;
public string Titre;
public string Categorie;
}
Now I instantiate the list:
List<Film> ListeFilms = new List<Film>();
And here is my event:
private void btSaveMovie_Click(object sender, EventArgs e)
{
var MyMovie = new Film(txtNum.Text, txtTitre.Text, cbCateg.Text);
ListeFilms.Add(MyMovie);
foreach (Film x in ListeFilms)
{
txtAffichage.AppendText(x.ToString());
}
}
Now when I run, all that is written in the text box is:
test_1.Form1+Film
What did I do wrong?
You have to override the ToString() method in the Film class declaration.Otherwise it returns the type name.
Example:
public class Film
{
public Film(string Num, string Title, string Categ)
{
this.Numero = Num;
this.Titre = Title;
this.Categorie = Categ;
}
public string Numero;
public string Titre;
public string Categorie;
public override string ToString()
{
return Numero.ToString() + " " + Titre.ToString() + " " + Categorie.ToString();
}
}
You just have to concatenate the three fields into the AppendText function:
private void btSaveMovie_Click(object sender, EventArgs e)
{
var MyMovie = new Film(txtNum.Text, txtTitre.Text, cbCateg.Text);
ListeFilms.Add(MyMovie);
foreach (Film x in ListeFilms)
{
txtAffichage.AppendText(x.Numero + " - " + x.Titre + "- " + x.Categorie));
}
}
Related
I am making an contact book to try to learn classes, and opening new forms.
I am trying to get items from a text document to populate a list box, using only the string before the first delimiter from each line. When I run the script, the Windows form appears, but the listbox is blank but there appears to be five items in it that are selectable. Clicking on them has no effect.
Here is my code for the form:
namespace AddressBook
{
public partial class formMain : Form
{
//Pub vars
string selectedName = "";
List<string> values = new List<string>();
public formMain()
{
InitializeComponent();
}
public void formMain_Load (object sender, EventArgs e)
{
//load values from file
try
{
StreamReader inputFile;
inputFile = File.OpenText("EmpRoster.txt");
string lines;
while (!inputfile.EndOfSteam)
{
lines = inputFile.ReadLine();
string[] tokens = lines.Split(',');
PersonEntry person = new PersonEntry(tokens[0], tokens[1], tokens[2]);
values.Add(person.Name + ";" + person.Email + ";" + person.Phone);
listOuput.Items.Add(person.Name);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//Selected index change
private void listOutput_SelectedIndexChanged(object sender, EventArgs e)
{
selectedName = listOutput.SelectedItem.ToString();
Form newForm = new Form();
Label label1 = new Label();
label1.Size = new Size(270, 75);
label1.Location = new Point(10, 10);
foreach (string str in values)
{
if (str.Containes(selectedName))
{
string[] tokens = str.Split(';');
label1.text += "Name: " + tokens[0] + "\n" + "Email: " + tokens[1] + "\n" + "Phone Number: " + tokens[2] + "\n";
}
}
newForm.Controls.Add(label1);
newForm.ShowDialog();
}
}
and here is my code for the class:
namespace AddressBook
{
public class PersonEntry
{
private string _name;
private string _email;
private string _phone;
public PersonEntry(string name, string email, string phone)
{
_name = "";
_email = "";
_phone = "";
}
public string Name
{
get { return _name; }
set { _name = value; }
}
public string Email
{
get { return _email; }
set { _email = value; }
{
public string Phone
{
get { return _phone; }
set { _phone = value; }
}
}
}
I cannot seem to get this to show at run; however, I did try adding a button and populating the listbox on click, and that seemed to work.
I'd appreciate some fresh eyes on this.
The problem lies on how you are instantiating your class. If you look at the constructor:
public PersonEntry(string name, string email, string phone)
{
_name = "";
_email = "";
_phone = "";
}
You are not storing the received values, but ignoring them completely. Just simplify your class to this:
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public PersonEntry(string name, string email, string phone)
{
Name = name;
Email = email;
Phone = phone;
}
You don't need to generate the backing fields, that's done automatically for you.
Your PersonEntry constructor is the issue. You are assigning empty strings where you should (presumably) be assigning the supplied parameters.
I'm trying to make a program which stores a bunch of country information from a country class in an AVL tree. I am using a form which prints out the list of countries which is saved in a CSV file and when I click on a country I want the program to print out information which corresponds to the selected country.
The problem I am having is getting it to print out the GDP in a text box when I select a country in the list box.
What code can I put to into list box which will print the gdp into a textbox?
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Country country = (Country)listBox1.SelectedValue;
}
.
namespace country
{
public partial class Form1 : Form
{
AVLTree<Country> myTree = new AVLTree<Country>();
List<Country> Countries = new List<Country>();
static string[] headers = new string[6];
string buffer = "";
public Form1()
{
InitializeComponent();
const int MAX_LINES_FILE = 50000;
string[] AllLines = new string[MAX_LINES_FILE];
AllLines = File.ReadAllLines("countries.CSV");
foreach (string line in AllLines)
{
if (line.StartsWith("Country"))
{
headers = line.Split(',');
}
else
{
string[] columns = line.Split(',');
LinkedList<string> tradePartner = new LinkedList<string>();
string[] partners = columns[5].Split(';', '[', ']');
foreach (string x in partners)
{
if (x != "")
{
tradePartner.AddLast(x);
}
}
myTree.InsertItem(new Country(columns[0], float.Parse(columns[1]), float.Parse(columns[2]), float.Parse(columns[3]), float.Parse(columns[4]), tradePartner));
}
}
myTree.PreOrder(ref buffer);
Console.WriteLine("Tree Contains " + buffer);
Add();
}
private void Add()
{
myTree.CInOrder(ref Countries);
foreach (Country y in Countries)
{
listBox1.Items.Add(y.Countryname);
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Country country = (Country)listBox1.SelectedValue;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
}
}
country class
public Country (string cn, float gd, float i, float tb, float hd, LinkedList<string> mt)
{
this.Countryname = cn;
this.gdp = gd;
this.inflation = i;
this.tradeBalance = tb;
this.hdi = hd;
this.mtp = mt;
}
public int CompareTo(object other)
{
Country temp = (Country)other;
return Countryname.CompareTo(temp.Countryname);
}
public override string ToString()
{
foreach (string i in mtp)
x += i + ",";
return Countryname + " " + gdp + " " + inflation + " " + tradeBalance +" " + hdi + " " + x;
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Country country = (Country)listBox1.SelectedValue;
if (country != null )
textBox1.Text = country.gdp;
}
In the combo box I can get it to load all the conversions to the combo box. But, when I click a conversion from the combo box it changes the data to null for some reason. I am not sure if anyone can help me without looking at all my code. But I thought it was worth a shot. I am trying to select a conversion I.e feet to miles and have the "feet" be in the first label and the "miles" be in the second. Here is the code for the click event of the combo box:
public void CmboBxConversion_SelectedIndexChanged(object sender, EventArgs e)
{
//This is not working. If I were to say change the conversion.From to "hello world" the label text does change to hello world.
//But, as is it is it changes it to a null.
Conversion conversion = new Conversion();
Lbl1stConv.Text = conversion.From; //these are labels
LblSecondConv.Text = conversion.To;
}
//this is my Conversion class
public class Conversion
{
public string From { get; set; }
public string To { get; set; }
public decimal Multiplier { get; set; }
public string GetDisplayText(string sep)
{
return From + ("|") + To + ("|") + Multiplier;
}
public string GetCmboBxText(string sep)
{
return From + (" to ") + To;
}
}
//this is how I am loading the combo box
private void Conversion_Load(object sender, EventArgs e)
{
conversions = ConversionDB.GetConversions();
FillConversionComboBox();
}
//here is the method used to fill the combobox
private void FillConversionComboBox()
{
CmboBxConversion.Items.Clear();
foreach (Conversion c in conversions)
{
CmboBxConversion.Items.Add(c.GetCmboBxText("\n"));
}
}
//this is a data base class that the textfile is pulling data
public static class ConversionDB
{
public const string Path = #"..\..\Conversions.txt";
//public const string Path = Dir + "Conversions.txt";
public static List<ConversionList> GetConversions()
{
StreamReader textIn = new StreamReader(
new FileStream(Path, FileMode.Open, FileAccess.Read));
List<ConversionList> conversions = new List<ConversionList>();
while (textIn.Peek() != -1)
{
string row = textIn.ReadLine();
string[] columns = row.Split('|');
ConversionList conversion = new ConversionList();
conversion.From = columns[0];
conversion.To = columns[1];
conversion.Multiplier = Convert.ToDecimal(columns[2]);
conversions.Add(conversion);
}
textIn.Close();
return conversions;
}
I'm not sure if this is what you want but it is a little simpler approach that gives you the same functionality. I think it will be much simpler if you bind the combobox to your list of conversions. The selecteditem and selectedvalue will be easier to work with.
public partial class Form1 : Form
{
private List<Conversion> conversions=new List<Conversion>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
loadconversions();
//foreach (Conversion c in conversions)
//{this.comboBox1.Items.Add(c); }
comboBox1.DataSource = conversions;
this.comboBox1.DisplayMember = "GetCmboBxText";
}
private void loadconversions()
{
fillconversions("feet","yards",3);
fillconversions("yard", "feet", 0.33m);
fillconversions("km", "mile", 0.54m);
fillconversions("mile", "km", 1.6m);
fillconversions("quarts", "gallons", 4);
}
private void fillconversions(string from, string to, decimal multiplier)
{
conversions.Add(new Conversion(from, to, multiplier));
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Conversion c = (Conversion)this.comboBox1.SelectedItem;
this.textBox1.Text = c.GetDisplayText;
}
}
public class Conversion
{
public string From { get; set; }
public string To { get; set; }
public decimal Multiplier { get; set; }
public Conversion(string from, string to, decimal multiplier)
{
From = from;
To = to;
Multiplier = multiplier;
}
public string GetDisplayText
{
get { return From + ("|") + To + ("|") + Multiplier; }
}
public string GetCmboBxText
{
get
{
return From + (" to ") + To;
}
}
}
I want to change my struct Patient to a class but when I do my program don't work(free of errors) I want to substitute the struct patient for class patientn, as you can see my button click uses the struct patient and I want to change it for a class and still work.
visual studio 10 My program:
public partial class Form1 : Form
{
int itemCountInteger;
public struct Patient
{
public string patientidstring;
public string firstNameString;
public string lastNameString;
}
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
public class Patientn
{
private int patientId;
public string firstName;
private string lastName;
public Patientn()
{
patientId = 0;
firstName = "";
lastName = "";
}
public Patientn(int idValue, string firstNameVal, string lastNameVal)
{
patientId = idValue;
firstName = firstNameVal;
lastName = lastNameVal;
}
}
//Array
Patient[] patientInfo = new Patient[10];
//this method is used to add items to array and display listbox
private void button1_Click(object sender, EventArgs e)
{
try
{
foreach (Patient patientinfoIndex in patientInfo)
patientInfo[itemCountInteger].patientidstring = textBox1.Text;
patientInfo[itemCountInteger].firstNameString = textBox2.Text;
patientInfo[itemCountInteger].lastNameString = textBox3.Text;
string names = patientInfo[itemCountInteger].firstNameString + " " + patientInfo[itemCountInteger].lastNameString;
listBox1.Items.Add(names);
itemCountInteger++;
listBox1.SelectedItem = names;
}
catch
{
MessageBox.Show("Contacts are limited to 20. Please delete some contacts prior to adding more.");
}
}
You should explicitly create class instances. In your case
// It's quite enough since Patient is a struct
Patient[] patientInfo = new Patient[10];
In case of Patientn that is class it should be
// As it was...
Patientn[] patientInfo = new Patientn[10];
// You should add this since Patientn is a class
for (int i = 0; i < patientInfo.Length; ++i)
patientInfo[i] = new Patientn();
My problem is that I have a List<> variable connected to another class, and I want to get all the items from that List<> and put it into a string.
In the result string, i'd like to see callNum, copyNum, content, author, year, title
Here is where I'm trying to put it into a string
public class CItemControl
{
//declare a list variable
private List<CItem> mItems;
private CItem mNewItem;
//a method that instantiates the list
public CItemControl()
{
mItems = new List<CItem>();
}
//attribute to get all items
public List<CItem> Items
{
get { return mItems; }
}
public CItem NewItem
{
get { return mNewItem; }
}
//method to add item to the CItem list
public void AddItem(int callNum, int copyNum, string content, string author, string year)
{
mNewItem = new CItem(callNum, copyNum, content, author, year);
mItems.Add(mNewItem);
}
//method to return all items to a string
public CItem ListAllItems()
{
string allItems;
}
Here is the class where I'm trying to get the items from. There will be variables added later.
class CItem
{
//declare attributes
private string mTitle;
private string mAuthor;
private string mContent;
private string mYear;
private int mCopyNum;
private int mCallNum;
private bool mHold = false;
private bool mBorrowed = false;
private bool mShelf = false;
//overload a constructor
public CItem(int CallNum, int CopyNum, string Content, string Author, string Year)
{
callNum = CallNum;
copyNum = CopyNum;
content = Content;
author = Author;
year = Year;
}
//create the default constructor
public CItem()
{
callNum = 0;
copyNum = 0;
content = "";
author = "";
year = "";
}
//set attributes
public int callNum
{
get { return mCallNum; }
set { mCallNum = value; }
}
public string content
{
get { return mContent; }
set { mContent = value; }
}
public string author
{
get { return mAuthor; }
set { mAuthor = value; }
}
public string year
{
get { return mYear; }
set { mYear = value; }
}
public string title
{
get { return mTitle; }
set { mTitle = value; }
}
public int copyNum
{
get { return mCopyNum; }
set { mCopyNum = value; }
}
public bool hold
{
get { return mHold; }
}
public bool borrowed
{
get { return mBorrowed; }
}
public bool shelf
{
get { return mShelf; }
}
//display information for users
public string displayInfo()
{
return "Call Number: " + callNum + ". Copy Number: " + copyNum + ". Title: " + title +
". Author: " + author + ". Year Published: " + year + ". Content: " + content;
}
//new method to display status of item
public string displayStatus()
{
if (borrowed == true)
return "Item is currently being borrowed.";
if (shelf == true && hold == false)
return "Item is available for borrowing.";
else
return "Item is on hold";
}
Any help is much appreciated!
Thanks in advance.
ListAllItems shall look something like this
public string ListAllItems()
{
var sb = new StringBuilder(); // var is of type StringBuilder
mItems.ForEach(item => sb.Append(item.displayInfo());
return sb.ToString();
}
return String.Join("; ", allItems.Select(item => item.displayInfo()));
You don't provide a lot of informations on how and what informations you want in your result string.
Can't you achieve this objective with a simple loop ?
using System.Text;
(...)
public string ListAllItems()
{
StringBuilder allItems = new StringBuilder();
foreach(CItem itm in Items){
allItems.AppendLine(itm.displayInfo());
}
return allItems.ToString();
}
Stringbuilder is optional but is faster than string concatenation.
I don't normally like to add formatter methods to property bags like this. If you want the flexibility to change have many formatting implementations, you might want to make a seperate class do the formatting.
public interface IFormatter<in T>
{
string Format(T obj);
}
public class CItemFormatter : IFormatter<CItem>
{
public string Format(CItem item)
{
//formatting logic
}
}