How do I populate a string array upon instantiation? - c#

So I have created a class that holds properties for the names of albums, including their genre, name and artist with an array that will hold the track list. When compiled, the properties' default values are replaced however I don't know how to replace the default values for the array - I don't know how to replace the default track listing with new tracks for each album. Thanks.
Here is the CD.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Exercise_2
{
class Cd
{
string name;
string artist;
string genre;
public string[] tracklist;
public string[] newTracklist;
public string getName()
{
return name;
}
public void setName(string newName)
{
name = newName;
}
public string getArtist()
{
return artist;
}
public void setArtist(string newArtist)
{
artist = newArtist;
}
public string getGenre()
{
return genre;
}
public void setGenre(string newGenre)
{
genre = newGenre;
}
public string[] getTracklist()
{
return tracklist;
}
public void setTracklist(string[] newTracklist)
{
string[] tracklist = newTracklist;
}
public Cd()
{
this.name = "CD Name";
this.artist = "CD Artist";
this.genre = "CD Genre";
this.tracklist = new string[3] { "Track1", "Track2", "Track3" };
this.newTracklist = new string[3] { "newTrack1", "newTrack2", "newTrack3" };
}
}
}
And here is the main.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Exercise_2
{
class Exercise2
{
static void Main()
{
Cd CD1 = new Cd();
CD1.setName("Kill 'Em All");
CD1.setArtist("Metallica");
CD1.setGenre("Thrash Metal");
Cd CD2 = new Cd();
CD2.setName("Ride The Lightning");
CD2.setArtist("Metallica");
CD2.setGenre("Thrash Metal");
Cd CD3 = new Cd();
CD3.setName("Master Of Puppets");
CD3.setArtist("Metallica");
CD3.setGenre("Thrash Metal");
Console.WriteLine(CD1.getName() + " - " + CD1.getArtist() + " - " + CD1.getGenre() + " - " + CD1.getTracklist());
Console.WriteLine(CD2.getName() + " - " + CD2.getArtist() + " - " + CD2.getGenre());
Console.WriteLine(CD3.getName() + " - " + CD3.getArtist() + " - " + CD3.getGenre());
}
}
}

The problem is your setTracklist method creates a new array every time:
public void setTracklist(string[] newTracklist)
{
string[] tracklist = newTracklist;
}
Instead, you need to set the instance tracklist member:
public void setTracklist(string[] newTracklist)
{
tracklist = newTracklist;
}
One more piece of advice. Don't create methods to get and set properties, it's just unnecessary work. Change:
string name;
string artist;
string genre;
public string[] tracklist;
public string[] newTracklist;
To:
public string Name {get; set;}
public string Artist {get; set;}
public string Genre {get; set;}
public string[] Tracklist {get; set;}
You also might want to change tracklist to a List<String> so you can easily add tracks:
public List<String> Tracklist {get; set;}
If you do this, you can create a Cd instance a lot easier:
var newCD = new Cd
{
Name = "Kill 'Em All",
Artist = "Metallica",
Genre = "Thrash Metal"
};
newCD.Tracklist.Add("Hit the Lights");
newCD.Tracklist.Add("The Four Horsemen");
newCD.Tracklist.Add("Motorbreath");
// etc etc
Update:
Here's the full code, in case something got mixed up. I've also implemented a getTracklist method which returns all the tracks is a comma delimited form.
using System;
using System.Collections.Generic;
class Cd
{
public string Name { get; set; }
public string Artist { get; set; }
public string Genre { get; set; }
public List<string> Tracklist { get; set; }
public Cd()
{
Name = "CD Name";
Artist = "CD Artist";
Genre = "CD Genre";
Tracklist = new List<string>();
}
public string getTracklist()
{
return String.Join(", ", Tracklist);
}
}
public class Exercise2
{
public static void Main()
{
Cd CD1 = new Cd();
CD1.Name = "Kill 'Em All";
CD1.Artist = "Metallica";
CD1.Genre = "Thrash Metal";
CD1.Tracklist.Add("Hit the Lights");
CD1.Tracklist.Add("The Four Horsemen");
CD1.Tracklist.Add("Motorbreath");
Cd CD2 = new Cd();
CD2.Name = "Ride The Lightning";
CD2.Artist = "Metallica";
CD2.Genre = "Thrash Metal";
Cd CD3 = new Cd();
CD3.Name = "Master Of Puppets";
CD3.Artist = "Metallica";
CD3.Genre = "Thrash Metal";
Console.WriteLine(CD1.Name + " - " + CD1.Artist + " - " + CD1.Genre + " - " + CD1.getTracklist());
Console.WriteLine(CD2.Name + " - " + CD2.Artist + " - " + CD2.Genre);
Console.WriteLine(CD3.Name + " - " + CD3.Artist + " - " + CD3.Genre);
}
}

You would just write
CD1.setTrackList(new string[] {"Hit The Lights", "The Four Horsemen", "Motorbreath"});
And your setTrackList should read:
public void setTracklist(string[] newTracklist)
{
tracklist = newTracklist;
}
The way you originally wrote it, you were creating a new array of tracks each time you were setting it, instead of setting the backing property.
However, there is a better way to do this. C# has what's called Auto Properties. They handle all this for you.
public string Name {get; set;}
public string Artist {get; set;}
//.... etc

Related

Trouble with Data Binding properties within custom Pin class using Xamarin Forms

I'm having trouble setting the data binding for some custom properties within a custom Pin class using Xamarin forms.
Here is the two custom classes I'm dealing with.
public class CustomPin : Pin
{
public static readonly BindableProperty NameProperty = BindableProperty.Create("Name", typeof(string), typeof(Pin), default(string));
public string Name
{
get { return (string)GetValue(NameProperty); }
set { SetValue(NameProperty, value); }
}
public string Icon { get; set; }
}
public class UserData
{
public string Callsign { get; set; }
public string ID { get; set; }
public string Team { get; set; }
public CustomPin Pin { get; set; }
public Position Position { get; set; }
}
Here is the element that holds the values of my Bindings.
public static UserData myUserData = new UserData
{
Callsign = "User",
Pin = new CustomPin
{
BindingContext = myUserData,
Position = new Position(),
Name = "",
Label = ""
},
Position = new Position(),
};
Here is how I set the bindings
myUserData.Pin.SetBinding(CustomPin.PositionProperty, "Position");
myUserData.Pin.SetBinding(CustomPin.LabelProperty, "Callsign");
myUserData.Pin.SetBinding(CustomPin.NameProperty, "Callsign");
And there is the method I use to debug
Debug.WriteLine
(
myUserData.Pin.Name + " should be " + myUserData.Callsign + "\n" +
myUserData.Pin.Label + " should be " + myUserData.Callsign + "\n" +
myUserData.Pin.Position.Latitude + " should be " + myUserData.Position.Latitude + "\n" +
myUserData.Pin.Position.Longitude + " should be " + myUserData.Position.Longitude + "\n"
);
Here is the output, as you can see it doesn't apply the bindings - however I do use this bindings in other objects (such as Xamarin.Forms.Label) and they work just fine.
should be User
should be User
0 should be 37.63150086
0 should be -122.43626643
Thank you in advance for any help.

Need help in C# to delete obj in a list

I have an employee management system which I'm trying to build in c# console application whereas im able to add a new employee.
but I'm not sure on how can I delete a employee from the list.
I have to put together both method then it works.
it seem like i'm unable to call the obj (emp) from my removeEmployee method
Main class
using System;
namespace HRM
{
class Program
{
static void Main(string[] args)
{
manageEmp emp = new manageEmp();
emp.addEmployee();
emp.removeEmployee();
}
}
}
Employee Class
using System;
using System.Collections.Generic;
namespace HRM
{
public class Employee
{
private String empID;
private String empFirstName;
private String empLastName;
private String empDep;
private String empDOB;
private String empAddress;
private int PostalCode;
private double empSal;
public Employee()
{
}
public Employee(String aempID, string aempFirstName, string aempLasttName, string aempDep, String aEmpDOB, string aempAddress, int aPostalCode, double aempSal)
{
this.EmpID = aempID;
this.EmpFirstName = aempFirstName;
this.EmpLastName = aempLasttName;
this.EmpDep = aempDep;
this.EmpDOB = aEmpDOB;
this.EmpAddress = aempAddress;
this.PostalCode1 = aPostalCode;
this.EmpSal = aempSal;
}
public string EmpID { get => empID; set => empID = value; }
public string EmpFirstName { get => empFirstName; set => empFirstName = value; }
public string EmpLastName { get => empLastName; set => empLastName = value; }
public string EmpDep { get => empDep; set => empDep = value; }
public string EmpDOB { get => empDOB; set => empDOB = value; }
public string EmpAddress { get => empAddress; set => empAddress = value; }
public int PostalCode1 { get => PostalCode; set => PostalCode = value; }
public double EmpSal { get => empSal; set => empSal = value; }
public List<Employee> El { get => el; set => el = value; }
public override string ToString()
{
return "Employment ID : " + empID + "\n"
+ "FirstName : " + EmpFirstName + "\n"
+ "LastName : " + EmpLastName + "\n"
+ "Department : " + EmpDep + "\n"
+ "Date of Birth: " + EmpDOB + "\n"
+ "Address : " + EmpAddress + "\n"
+ "PostalCode : " + PostalCode1 + "\n"
+ "empSal : " + EmpSal + "\n";
}
}
}
manageEmp class
using System;
using System.Collections.Generic;
namespace HRM
{
public class manageEmp
{
private List<Employee> el = new List<Employee>();
public List<Employee> El { get => el; set => el = value; }
public void addEmployee()
{
Console.WriteLine("===================================" + "\n");
Console.WriteLine("Add an Employee");
Console.WriteLine("===================================" + "\n");
Console.WriteLine("");
Console.WriteLine("Please enter your Employment ID");
String eID = Console.ReadLine();
Console.WriteLine("Please enter your First Name");
String eFirstName = Console.ReadLine();
Console.WriteLine("Please enter your Last Name");
String eLasttName = Console.ReadLine();
Console.WriteLine("Please entter your department");
String eDep = Console.ReadLine();
Console.WriteLine("Please enter your Date of Birth");
String eDOB = Console.ReadLine();
Console.WriteLine("Please entter your Address");
String eAddress = Console.ReadLine();
Console.WriteLine("Please enter your Postal Code");
int ePostalCode = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please enter your Salary");
double eSal = Convert.ToDouble(Console.ReadLine());
Employee emp = new Employee(eID, eFirstName, eLasttName, eDep, eDOB, eAddress, ePostalCode, eSal);
emp.El.Add(emp);
}
public void viewEmployee()
{
Employee nemp = new Employee();
nemp.El.ForEach(Console.WriteLine);
}
public void removeEmployee()
{
Console.WriteLine("Please enter a employee Id to be deleted");
String delemp = Console.ReadLine();
for (int i = 0; i < El.Count; i++)
{
emp = El[i];
if (delemp.Equals(eID))
{
el.Remove(emp);
}
Console.WriteLine(delemp + " Has been deleted sucessfully");
el.ForEach(Console.WriteLine);
}
}
}
}
Your problem is that your employee list is inside the employee class -- so each of the employees has its own list of employees -- and that list only contains that single employee.
In the function RemoveEmployee you are creating a new manageEmp object. As the word 'new' implies, this is a different, newly created manageEmp with its own, newly created List<Employee> which doesn't contain any items.
Further, you have declared the function as public void removeEmployee(string eID) so you can't call it with the line emp.removeEmployee().

C# parse textual file in a specific format

I have never done something like this so I'm really curious on how this can be performed. I imagine it can be either done via regex or in c# somehow...
I have a textual file with data in following format:
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
I have prepared a class which looks like following:
public class ParsedData
(
public string IP { get; set; }
public string Port { get; set; }
public string Username { get; set; }
public string Password { get; set; }
)
The desired output how I would like it to be is that I can parse each line individually and 1 line should have the data stored in a parsed object (list of ParsedData);
How could do this, and to parse the each line of data individually ?
Can someone help me out ?
var completedList = text.Split(':').Select(pr => new ParsedData
{
IP = pr.ElementAt(0).ToString() // this should be the IP But I'm getting the
// Index was outside the bounds of the array. exception in this part
/*My elements here*/
}).ToList();
It looks like at least one row doesn't have any data in it, maybe there is an empty row in the input data?
Try printing out each row of data before selecting the first element of the array - then you can see which input is causing the exception.
You may use Regex (.+?):(.+?):(.+?):(.+), here example:
using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;
namespace Main {
public struct ParsedData {
public string IP { get; set; }
public string Port { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
class Prog {
static List<ParsedData> pdl = new List<ParsedData>();
static string file = #"12.23.425.56:90:kukur:psiar%4
151.23.255.52:3131:Zandga:Ikurit
52.23.45.56:5125:Ningame:Mirsga!#
112.223.45.56:4000:Bisgo:One0ne";
static void Main() {
var re = new Regex(#"(.+?):(.+?):(.+?):(.+)");
foreach (Match m in re.Matches(file)) {
pdl.Add(new ParsedData() { IP = m.Groups[1].Value, Port = m.Groups[2].Value, Username = m.Groups[3].Value, Password = m.Groups[4].Value });
Console.WriteLine("IP: " + m.Groups[1] + " PORT: " + m.Groups[2] + " USR_NM: " + m.Groups[3] + " PASS: " + m.Groups[4]);
}
}
}
}
Also I added an List which contains the data.
class Program
{
static void Main(string[] args)
{
//I think you know how to read the file so:
string text =
#"12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password
12.23.45.56:8080:username:password";
List<ParsedData> ps = new List<ParsedData>();
text.Split(new char[] { '\r','\n' }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach(c =>
{
var cols = c.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries).ToList();
//you can check too if cols have content here
ps.Add(new ParsedData()
{
IP = cols[0]!=null?cols[0]:"", //and check if inside it's content..
Port = cols[1],
Username = cols[2],
Password = cols[3]
});
});
foreach(ParsedData p in ps)
{
Console.WriteLine(p.IP + "\t" + p.Port + "\t" + p.Username + "\t" + p.Password);
}
}
}
public class ParsedData
{
public string IP { get; set; }
public string Port { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
I think you make misunderstood about the pr, it not array now, it the element in the array.
var text = "12.23.45.56:8080:username:password";
var array = text.Split(':');
var data = new ParsedData()
{
IP = array[0],
Port = array[1],
Username = array[2],
Password = array[3]
};

Adding an Additional Struct to hold data which then prints out in the console window

I have been given this code to change, I have already added a struct with the initial student information in it and it runs fine the code is below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Program
{
class Student
{
public struct student_data
{
public string forename;
public string surname;
public string prog_title;
public string prog_code;
public int id_number;
public float averageGrade;
}
static void populateStruct(out student_data student, string fname, string surname, string prog_title, string prog_code, int id_number)
{
student = new student_data();
student.forename = fname;
student.surname = surname;
student.prog_title = prog_title;
student.prog_code = prog_code;
student.id_number = id_number;
student.averageGrade = 0.0F;
}
static void Main(string[] args)
{
student_data[] students = new student_data[4];
populateStruct(out students[0], "Mark", "Anders", "Comp", "CIS2117", 0);
printStudent(students[0]);
populateStruct(out students[1], "Tom", "Jones", "Comp", "CIS2117", 1);
printStudent(students[1]);
populateStruct(out students[2], "Tim", "Jones", "Comp", "CIS2117", 2);
printStudent(students[2]);
populateStruct(out students[3], "Tim", "Bones", "Comp", "CIS2117", 3);
printStudent(students[3]);
}
void printAllStudent(student_data student)
{
for (int i = 0; i <= 3; i++)
{
Console.WriteLine(i);
}
}
static void printStudent(student_data student)
{
Console.WriteLine("Name: " + student.forename + " " + student.surname);
Console.WriteLine("Id: " + student.id_number);
Console.WriteLine("AV grade: " + student.averageGrade);
Console.WriteLine("Course Title: " + student.prog_title);
Console.WriteLine("Course Code: " + student.prog_code);
}
}
}
But I was tasked with adding another Struct to hold module_data which I've done, I've also created a new method to populate the module_data array. But when I run the program only one error shows up and nothing happens?
It is meant to WriteLine all the elemmnts in the arrays in the console screen but will not build and produces this error:
'Error 1 The type or namespace name 'module_data' could not be found (are you missing a using directive or an assembly reference?)'
The Code is below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Program
{
class Student
{
public struct student_data
{
public string forename;
public string surname;
public string prog_title;
public string prog_code;
public int id_number;
public float averageGrade;
}
public struct module_data
{
public string module_code;
public string module_title;
public int module_mark;
}
static void populateStruct(out student_data student, string fname, string surname, string prog_title, string prog_code, int id_number)
{
student = new student_data();
student.forename = fname;
student.surname = surname;
student.prog_title = prog_title;
student.prog_code = prog_code;
student.id_number = id_number;
student.averageGrade = 0.0F;
}
static void populateModule(out module_data module, string mcode, string mname, int (score)
{
module = new module_data();
module.module_code = mcode;
module.module_title = mname;
module.module_mark = score;
}
static void Main(string[] args)
{
{
student_data[] students = new student_data[5];
populateStruct(out students[0], "Mark", "Anderson", "Comp", "CIS2117", 0);
printStudent(students[0]);
populateStruct(out students[1], "Tom", "Jones", "Comp", "CIS2117", 1);
printStudent(students[1]);
populateStruct(out students[2], "Tim", "Jones", "Comp", "CIS2117", 2);
printStudent(students[2]);
populateStruct(out students[3], "Tim", "Bones", "Comp", "CIS2117", 3);
printStudent(students[3]);
}
{
module_data[] modules = new module_data[4];
populateStruct(out modules[0], "7", "App Dev", "56", 0);
printStudent(modules[0]);
populateStruct(out modules[1], "7", "App Dev", "56", 1);
printStudent(module[1]);
populateStruct(out modules[2], "7", "App Dev", "56", 2);
printStudent(modules[2]);
populateStruct(out modules[3], "7", "App Dev", "56", 3);
printStudent(modules[3]);
Console.ReadKey();
}
}
void printAllStudent(student_data student)
{
for (int i = 0; i <= 3; i++)
{
Console.WriteLine(i);
}
}
static void printStudent(student_data student)
{
Console.WriteLine("Name: " + student.forename + " " + student.surname);
Console.WriteLine("Id: " + student.id_number);
Console.WriteLine("AV grade: " + student.averageGrade);
Console.WriteLine("Course Title: " + student.prog_title);
Console.WriteLine("Course Code: " + student.prog_code);
Console.WriteLine("Module Code: " + modules.mcode);
Console.WriteLine("Module Name: " + modules.mname);
Console.WriteLine("Score: " + modules.score);
}
}
}
In all truth not sure where I've gone wrong, any help or advice would be appreciated.
I'm not sure if a module is something a student has. This answer has them independent. Although the code needs additional work this will at least clean up your code and get you started. There are naming conventions that aren't followed here and other standards.
I would suggest you write one small piece of functionality and get that to work before moving on to something else. You had many errors in your code which wouldn't compile. Fixing an error as it occurs and testing small pieces will help you figure out what the problem is.
The links below are to explain comments in the code
Choosing Between Class and Struct
Default constructors
How to: Initialize Objects by Using an Object Initializer
Array Class showing it implements IEnumerable
class Program
{
//Use a class instead of a struct to store your data in most cases... see link
public class Student
{
public string forename { get; set; }
public string surname { get; set; }
public string prog_title { get; set; }
public string prog_code { get; set; }
public int id_number { get; set; }
public float averageGrade { get; set; }
//I ommited the defualt {} constructor so this is your only choice to create a new class
//you may want to choose to put it back in for more flexibility...see link
public Student(string fname, string surname, string prog_title, string prog_code, int id_number)
{
forename = fname;
this.surname = surname;
this.prog_title = prog_title;
this.prog_code = prog_code;
this.id_number = id_number;
averageGrade = 0.0F;
}
}
public class module_data
{
public string module_code { get; set; }
public string module_title { get; set; }
public int module_mark { get; set; }
public module_data(string mcode, string mname, int score)
{
module_code = mcode;
module_title = mname;
module_mark = score;
}
}
static void Main(string[] args)
{
//I'm initializing the array using object initialization syntax ... see link
Student[] students = new Student[4]
{
new Student( "Mark", "Anderson", "Comp", "CIS2117", 0),
new Student( "Tom", "Jones", "Comp", "CIS2117", 1),
new Student ("Tim", "Jones", "Comp", "CIS2117", 2),
new Student( "Tim", "Bones", "Comp", "CIS2117", 3)
};
module_data[] modules = new module_data[4]
{
new module_data( "7", "App Dev", 0),
new module_data( "7", "App Dev", 1),
new module_data("7", "App Dev", 2),
new module_data("7", "App Dev", 3)
};
printAllStudent(students);
Console.ReadKey();
}
//Because an array implements IEnumerable you should use a foreach loop instead of a for loop
static void printAllStudent(Student[] students)
{
foreach (Student s in students)
{
printStudent(s);
}
}
//You could pass a null in here and this would have a run-time error.
//It would be safer to check if student!=null here first (but I left it for you)
static void printStudent(Student student)
{
Console.WriteLine("Name: " + student.forename + " " + student.surname);
Console.WriteLine("Id: " + student.id_number);
Console.WriteLine("AV grade: " + student.averageGrade);
Console.WriteLine("Course Title: " + student.prog_title);
Console.WriteLine("Course Code: " + student.prog_code);
}
static void printModule(module_data m)
{
Console.WriteLine("Module Code: " + m.module_code);
Console.WriteLine("Module Name: " + m.module_title);
Console.WriteLine("Score: " + m.module_mark);
}
}

Getters and Setters, getting multiple fields

public class Teams : INotifyPropertyChanged
{
public string CombinedTeams
{
get
{
return Combined;
}
set
{
{
CombinedTeams += value;
NotifiyPropertyChanged("Combined");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifiyPropertyChanged(string p)
{
if (null != p)
{
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
}
private string Combined
{
get
{
return " " + HomeTeam + " " + HomeScore + " - " + AwayScore + " " + AwayTeam;
}
set
{
{
Combined += value;
}
}
}
public string HomeTeam { get; set; }
public string AwayTeam { get; set; }
public string HomeScore { get; set; }
public string AwayScore { get; set; }
}
I got a problem, when trying combine my strings together and having one LONG string that contains all the values from when I parse my XML I only get the First set of values,
basically I get
Team1 Score1 : Score2 Team2
as opposed to
Team1 Score1 : Score2 Team2 Team3 Score3 : Score4 Team4 Team5 Score5 : Score6 Team6
I am binding my Control to CombinedTeams
could you guys help me out? I just want to store the previous string and then combine the new string with the old one, I cant see it being hard but this is confusing me and reading up on it makes me more confused...
Thanks,
John
Your code concatenates the new value to an empty string (last = "").
You probably want to concatenate to the previous value.
I'm not sure what you are expecting, last is always initialized to "", so the += is irrelevant.
Seems like the class called Teams is really a game?
And I don't think setting HomeTeam, AwayTeam, HomeScore, AwayScore over and over again (and then saving this internally somehow) is a good way to keep track of multiple games.
Why don't you look at using a collection of games?
Try something like this:
In a GamesLib library:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace GamesLib
{
public class Game
{
public string HomeTeam { get; private set; }
public string AwayTeam { get; private set; }
public string HomeScore { get; private set; }
public string AwayScore { get; private set; }
public string Combined
{
get
{
return " " + HomeTeam + " " + HomeScore + " - " + AwayScore + " " + AwayTeam;
}
}
public Game(string HomeTeam, string AwayTeam, string HomeScore, string AwayScore)
{
this.HomeTeam = HomeTeam;
this.HomeScore = HomeScore;
this.AwayTeam = AwayTeam;
this.AwayScore = AwayScore;
}
}
public class Games : List<Game>, INotifyPropertyChanged
{
public string CombinedTeams
{
get
{
var str = "";
foreach (Game g in this)
{
str += g.Combined;
}
return str;
}
}
public new void Add(Game g)
{
base.Add(g);
if ( PropertyChanged != null ) {
PropertyChanged(this, new PropertyChangedEventArgs("CombinedTeams"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
In a console program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GamesLib;
namespace TestHarness
{
class Program
{
static void Main(string[] args)
{
var gs = new GamesLib.Games();
gs.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(gs_PropertyChanged);
var g = new Game("hometeam", "awayteam", "1", "0");
gs.Add(g);
g = new Game("lions", "bears", "1", "0");
gs.Add(g);
Console.WriteLine("Final result:" + gs.CombinedTeams);
}
static void gs_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
var gs = sender as Games;
Console.WriteLine("Changed: " + gs.CombinedTeams);
}
}
}
The reason you are getting the incorrect results is because you have one property referring to another property, and the second property always returns a specific value.
This block of code, when called from elsewhere, will return the results of some other variable called "Combined" which you have defined below...
public string CombinedTeams
{
get
{
return Combined;
}
...
}
private string Combined
{
get
{
return " " + HomeTeam + " " + HomeScore + " - " + AwayScore + " " + AwayTeam;
}
...
}
Everything else is academic because you're getter(s) essentially always return " " + HomeTeam + " " + HomeScore + " - " + AwayScore + " " + AwayTeam.
I suspect you will want to restructure your code to be something more like this
public class Teams : INotifyPropertyChanged
{
private string Combined; // Backing for CombinedTeams
public string CombinedTeams
{
get
{
return Combined;
}
set
{
// This only concatinates values; Combined will get longer each time.
Combined += value;
// ViewModels should always notify after the vale has changed
NotifyOfPropertyChange("CombinedTeams");
}
}
// Adds a new team, assuming HomeTeam, HomeScore, AwayScore, and AwayTeam have been initialized
public void AddTeam()
{
CombinedTeams = " " + HomeTeam + " " + HomeScore + " - " + AwayScore + " " + AwayTeam;
}
}
Certainly there are better ways to do that, but that should get you a start, I hope.
General rule (broken all the time by the code-ninjas, which is fine) is that a Property shouldn't do any calculations of it's own, it's really there to allow public access to private data in the class.
It might be worthwhile to run through a couple of articles on C# Properties. Here are some suggestions to get you started: http://msdn.microsoft.com/en-us/library/x9fsa0sw(v=vs.80).aspx and http://msdn.microsoft.com/en-us/library/aa288470(v=vs.71).aspx and of course, some Good Search Results

Categories