Populating a ListView with objects from a List<>
I am currently converting what was a Console Application into a Windows Form application. Fortunatly i initially designed the application to work with a GUI in the future so there was not much code to change.
I have a UserCollection class which itself holds a List<> of type User/Member (Member is derives from User).
What i would like to do is to add each item in the UserCollection List<> to the ListView, so i can see each entry and have the multiple entries list vertically.
I have tried to implement this myself firstly by using:
private void UpdatePeopleListings()
{
foreach (User person in newCollection)
{
listViewPeople.Items.Add(person.ToString());
}
}
Where newCollection is the new object created from the UserCollection class in the main windows form.
I recieve the error:
foreach statement cannot operate on variables of type 'Collection.UserCollection' because 'Collection.UserCollection' does not contain a public definition for 'GetEnumerator'
I then tried to make a small workaround, so in my UserCollection i created the following method:
public User ReturnUser()
{
foreach (User person in _userCollection)
{
return person;
}
return null;
}
(_userCollection is the List<> of Users/Members in UserCollection.cs)
And then use it like this:
private void UpdatePeopleListings()
{
listViewPeople.Items.Add(newCollection.ReturnUser().ToString());
}
Although this does populate the ListView with an entry, it only populates the first entry. If i was to add more than one User/Member to the newCollection then it simply repeats the first entry.
How would i go about populating the ListView with ALL objects in the collection properly and how would i prevent it from repeating only one object.
UserCollecton.cs
///////////////////////////////////////////////////////////
// UserCollection.cs
// Implementation of the Class UserCollection
// Generated by Enterprise Architect
// Created on: 22-Oct-2009 22:40:30
///////////////////////////////////////////////////////////
#region Using Statements
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
#endregion
namespace Collection
{
//Allows the class to be saved
[Serializable()]
public class UserCollection
{
#region Fields
//Declares a list of type User (Which also holds derived Member objects)
private List<User> _userCollection = new List<User>();
//Holds number of members
int nMember = 0;
//Holds number of users
int nUser = 0;
#endregion
#region Add Operations
/// <summary>
/// Adds a new user
/// </summary>
/// <param name="user"></param>
public void AddUser(User user)
{
//Adds the user given in the operation parameters to the collection
_userCollection.Add(user);
nUser++;
//Sorts the collection using the CompareTo() specified in the User class.
_userCollection.Sort();
//Console.WriteLine used for testing purposes
//Console.WriteLine("added");
}
///<summary>
///Adds a new Member
///</summary>
/// <param name="member"></param>
public void AddMember(Member member)
{
//Adds the member given in the operation parameters to the collection
_userCollection.Add(member);
nMember++;
//Sorts the collection using the CompareTo() specified in the User class.
_userCollection.Sort();
//Console.WriteLine used for testing purposes
//Console.WriteLine("added");
}
#endregion
#region Removal Operations
///<summary>
///Removes a user based on FirstName,LastName and PostCode
///</summary>
/// <param name="person"></param>
public void RemoveUser(User person)
{
//Only search collection for users if there is data in it
if (_userCollection.Count > 0)
{
//Create a temp list for any matched found
List<User> tempList = new List<User>();
foreach (User u in _userCollection)
{
//If the details stored in the collection match the details given in the search
if (u.FName == person.FName && u.LName == person.LName && u.PostCode == person.PostCode)
{
//Add any matches to the temp list
tempList.Add(u);
}
else
{
throw new ArgumentException("User not found");
}
}
//Delete any matches
foreach (User u in tempList)
{
_userCollection.Remove(u);
//Decrement user count
nUser--;
}
}
else
{
throw new AccessViolationException("No data in collection");
}
}
/// <summary>
/// Removes a user using Membership number
/// </summary>
/// <param name="number"></param>
public void RemoveMember(int number)
{
//Create a temp list of type Member
Member temp = new Member();
//Use the temp list to compare types and store all objects of type member
//found in the collection to it.
List<User> Mems = _userCollection.FindAll(delegate(User u)
{ return u.GetType() == temp.GetType(); });
//Delete any matches
foreach (Member m in Mems)
{
if (m.mNum == number)
{
_userCollection.Remove(m);
//Decrement member count
nMember--;
}
else
{
throw new ArgumentException("Member not found");
}
}
}
#endregion
#region Search Operations
///<summary>
///Returns member by Membership number
/// </summary>
///
/// <param name="_mNumber"></param>
public Member FindByMNo(int number)
{
//Create a temp list of type Member
开发者_如何学C Member temp = new Member();
//Use the temp list to compare types and store all objects of type member
//found in the collection to it.
List<User> Mems = _userCollection.FindAll(delegate(User u)
{ return u.GetType() == temp.GetType(); });
//Return any matches found
foreach (Member i in Mems)
{
if (i.mNum == number)
{
return i;
}
}
throw new ArgumentException("Member not found");
}
///<summary>
///Returns a list of Users matching details given
///</summary>
///
/// <param name="_fName"></param>
/// <param name="_lName"></param>
public List<User> FindByName(User person)
{
//Create a temp list to store any matches
List<User> temp = new List<User>();
//Add matches found to the temp list
foreach (User u in _userCollection)
{
if (u.LName == person.LName)
{
temp.Add(u);
}
}
if (temp.Count > 0)
{
//Return the list that holds any matches
return temp;
}
throw new ArgumentException("User not found");
}
public User ReturnUser()
{
foreach (User person in _userCollection)
{
return person;
}
return null;
}
#endregion
#region Edit Operations
///<summary>
///Edits a members membership expiry
///</summary>
///
/// <param name="member"></param>
public void EditMemStatus(int member, DateTime newDate)
{
//Create a temp list of type Member
Member temp = new Member();
//Use the temp list to compare types and store all objects of type member
//found in the collection to it.
List<User> Mems = _userCollection.FindAll(delegate(User u)
{ return u.GetType() == temp.GetType(); });
//Search for the member that matches the number given in the parameter
foreach (Member m in Mems)
{
if (m.mNum == member)
{
//Replace the match with the new expiry
m.mExp = newDate;
}
else
{
throw new ArgumentException("Date cannot be changed");
}
}
}
#endregion
#region I/O Operations
public bool SaveData()
{
try
{
//Open the stream using the Data.txt file
using (Stream stream = File.Open("Data.txt", FileMode.Create))
{
//Create a new formatter
BinaryFormatter bin = new BinaryFormatter();
//Copy data in collection to the file specified earlier
bin.Serialize(stream, _userCollection);
bin.Serialize(stream, nMember);
bin.Serialize(stream, nUser);
//Close stream to release any resources used
stream.Close();
}
return true;
}
catch (IOException ex)
{
throw new ArgumentException(ex.ToString());
}
}
public bool LoadData()
{
//Check if file exsists, otherwise skip
if (File.Exists("Data.txt"))
{
try
{
using (Stream stream = File.Open("Data.txt", FileMode.Open))
{
BinaryFormatter bin = new BinaryFormatter();
//Copy data back into collection fields
_userCollection = (List<User>)bin.Deserialize(stream);
nMember = (int)bin.Deserialize(stream);
nUser = (int)bin.Deserialize(stream);
stream.Close();
//Sort data to ensure it is ordered correctly after being loaded
_userCollection.Sort();
return true;
}
}
catch (IOException ex)
{
throw new ArgumentException(ex.ToString());
}
}
else
{
//Console.WriteLine present for testing purposes
Console.WriteLine("\nLoad failed, Data.txt not found");
return false;
}
}
#endregion
#region Properties
//Gets amount of Members in collection
public int GetNMember
{
get
{
return nMember;
}
}
//Gets amount of Users in collectioj
public int GetNUser
{
get
{
return nUser;
}
}
#endregion
}//end UserCollection
}
Ignore any random Console stuff, i've not finished the cleanup yet.
The foreach doesn't work because your UserCollection class doesn't implement the IEnumerable interface.
The ListItems is not what you expected, because you do not understand how the ListView / ListViewItems work. A ListView consists of ListViewItems, and a ListViewItem can consists of SubItems (which are only displayed when the ListView's viewstyle is set to 'report').
When you add a ListViewItem using the method that you're using, only the 'caption' of the ListViewItem is defined. This means, that you'll have to use another overload of the Add method; the method which takes a ListViewItem object as an argument. Then, you can do this:
ListViewItem item = new ListViewItem();
item.Text = "bar";
item.SubItems.Add ("foo");
item.SubItems.Add ("foo2");
myListView.Items.Add (item);
On the question that only one item is added to your list: - you are only adding one item ... More specifically, you're adding the collection itself, rather then creating a ListViewItem for each object that is in your collection.
So what you have to do is:
- iterate over your list (using foreach (means you have to implement IEnumerable on the collection class), or using a for loop (but you'll have to make sure that you can access the contents of the collection using an indexer for instance))
- create a ListViewItem for each object that exists in the list.
I wonder why you've created your custom UserCollection in the first place though. I see that you've implemented some specific functionality, but .... I think there are better solutions. Nonetheless, you should implement the IEnumerable interface, the IList interface, etc... for that class. By doing so, your class will be a 'real collection', and then you can work with it like any other collection class. (Iterate using foreach, or using a for loop, etc..)
In conjunction with Frederik Gheysel's answer, it would be wise to implement IEnumerator also. Remember to override Equals, GetHashCode and ToString when doing so.
精彩评论