Simply derive (inherit) your custom Type(s) from the desired Type/Interface, to access shared Properties, Methods, and Events:
Why you do a class that CONTAINS a List<T> instead of do a class that IS List<T> (that is, derive a class based on List<T>) for your simple Collection need?
...
Then the class has already the regular Add()/Remove()/Clear() methods available. You simply add your own properties/methods that List<T> do not have.
That seems to be simple enough ... it seems as though I have complicated it.
So, if I create my manager class and inherit List<T> then I don't even need to implement the properties for the collection?
Inheritance Terminology (http://msdn.microsoft.com/en-us/library/ms973803.aspx)
There are three types of inheritance that .NET supports: implementation, interface, and visual. Implementation inheritance refers to the ability to use a base class's properties and methods with no additional coding. Interface inheritance refers to the ability to use just the names of the properties and methods, but the child class must provide the implementation. Visual inheritance refers to the ability for a child form (class) to use the base forms (class) visual representation as well as the implemented code.
A class in .NET may inherit from a class that has already inherited from another class. In addition you may use an interface or even multiple interfaces within a class.
Then I don't need to do anything? Can it be that easy?
The only part that I am unclear with now, is how can I call the private method in ShiftManager to clear all items from the control and populate it with the new collection once the collection or an item in the collection has changed?
I am just starting to learn MVC 4, and maybe some else knows but I thought you could easily bind data to your controls, but I do not know enough.
If "Items" is a property of FacilityManager, why create an event for ItemAdded? Why not call _listControl.Add(sender.ToListItem) in the setter?
See if this makes sense:Code - C#: [Select]
Class FacilityManager { private object _listControl; _fc.ItemAdded += fc_ItemAdded; FacilityCollection property Items() { get { return _fc; } private set(FacilityCollection collection) { _fc = collection; } } static void fc_ItemAdded(object sender, ListItemEventArgs e) { if !e.IsTransient { if AddItemToControl((FacilityItem)sender) { //Do other work here } } } private AddItemToControl(FacilityItem item) { bool success = false; { case "ListType1": ListType1 _listObj = (ListType1)_listControl; _listObj.Add(item.ToListType1Item); success = true; break; case "ListType2": ListType2 _listObj = (ListType2)_listControl; _listObj.Add(item.ToListType1Item); success = true; break; case "ListType3": ListType3 _listObj = (ListType3)_listControl; _listObj.Add(item.ToListType1Item); success = true; break; case "ListType4": ListType4 _listObj = (ListType4)_listControl; _listObj.Add(item.ToListType1Item); success = true; } return success; } } Class FacilityCollection { private List<FacilityItem> _contents; public event ItemAdded(object sender, ListItemEventArgs e); void Add(FacilityItem item) { _contents.Add(item) ; } }
There may be a better way of dealing with what I am doing, but if there is, I don't see it.
I could do as you suggest and simply add the new FacilityItem directly to the _listControl from the FacilityManager, but I would have to create another function to do it .. and then I would still have to add the item to the FacilityCollection.
I suppose I could simply let FacilityCollection inherit List<FacilityItem> and then manipulate it as though FacilityCollection is nothing more than a List<FacilityItem> with some additional methods and properties that I define ... but I would still have to run the function to add the object to the control.
At least this way, when _contents is added to, FacilityManager knows about it and can do what it needs to do whenever the collection changes.
Unless I have completely missed the point ... and that wouldn't be unreasonable ...
string.join(", ", Items.Select(str => str.[strprop]))
...otherwise you might get something like namespace.FacilityItem, namespace.FacilityItem... due to System.Object.ToString() that you must override.skinning cats
public class FacilityItem
{
private string name;
public string Name
{ get {return name;}
set {name = value;}
}
private string discipline;
public string Discipline
{ get { return discipline;}
set { discipline = value;}
}
public FacilityItem()
{}
public FacilityItem(string facilityName)
{ name = facilityName;}
}
public class Facility : CollectionBase
{
#region properties
public string GetDisciplineList()
{
return string.Join(", ", List.OfType<FacilityItem>().ToList().Select(str => str.Name.ToString()));
}
//enable int indexing
public FacilityItem this[int itemIndex]
{
get { return (FacilityItem)List[itemIndex]; }
set { List[itemIndex] = value; }
}
//enable string indexing
public FacilityItem this[string itemIndex]
{
get
{
foreach (FacilityItem item in List)
{
if (item.Name == itemIndex)
return item;
}
return null;
}
}
#endregion
#region initialization methods
//no facilityitem needed, string or otherwise
public FacilityList()
{}
//usefull in new from cloning
public FacilityList(IEnumerable<FacilityItem> initialItems)
{
foreach (FacilityItem item in initialItems)
Add(item);
}
//alternative, usefull if creating several facilities the same
public FacilityList(IEnumerable<string> initialItems)
{
foreach (string item in initialItems)
List.Add(item);
}
//single initializer for facilitylist
public FacilityList(string initialItem)
{
List.Add(initialItem);
}
#endregion
#region maintenance overrides
//strongly typed maintenance make API usable
public void Add(FacilityItem newItem)
{ List.Add(newItem); }
public void Add(string newItem)
{ List.Add(new FacilityItem(newItem)); }
public FacilityItem Add(string newItem)
{
FacilityItem it = new FacilityItem(newItem);
List.Add(it);
return it;
}
public void Remove(FacilityItem oldItem)
{ List.Remove(oldItem); }
public void Remove(string oldItem)
{ List.Remove(oldItem); }
//deep cloning could go here if needed
#endregion
}
public class Grade
{
private int score;
public int Score
{
get
{
return score;
}
set
{
if (value <= 100 && value >= 0)
score = value;
else
throw (new ArgumentOutOfRangeException("Score", value,
"Please enter a percentage based grade [0~100]"));
}
}
//public Grade(Grade newGrade)
//{
// score = newGrade.Score;
//}
//private Grade()
//{
//}
public override string ToString()
{
return Score.ToString();
}
}
public class Grades : CollectionBase
{
public double Average()
{
int tally = 0;
foreach (Grade storedGrades in List)
{
tally += storedGrades.Score;
}
return Convert.ToDouble(tally) / List.Count;
}
public void Add(Grade newGrade)
{
List.Add(newGrade);
}
public void Remove(Grade oldGrade)
{
List.Remove(oldGrade);
}
public Grade this[int gradeIndex]
{
get
{
return (Grade)List[gradeIndex];
}
set
{
List[gradeIndex] = value;
}
}
}
public class Student
{
private Grades grades = new Grades(); //not sure if the Grades collection should be a property?
//private Grade[] grades;
private string studentName;
//public readonly string studentName;
public Grades Grades
{
get
{
return this.grades;
}
}
public string StudentName
{
get
{
return studentName;
}
set
{
StudentName = studentName;
}
}
public Student(string newStudentName)
{
studentName = newStudentName;
}
private Student()
{
}
}