2009-11-27 40 views
1

我目前正在將什麼是控制檯應用程序轉換爲Windows窗體應用程序。 幸運的是,我最初設計的應用程序在未來使用GUI,所以沒有太多的代碼需要改變。使用列表中的對象填充ListView <>

我有一個UserCollection類,它自己擁有一個類型爲User/Member(成員源自用戶)的列表<>。

我想要做的是將UserCollection列表中的每個項目添加到ListView中,這樣我就可以看到每個條目並垂直放置多個條目列表。

我曾嘗試這種利用先行先自己:

 private void UpdatePeopleListings() 
    { 
     foreach (User person in newCollection) 
     { 
      listViewPeople.Items.Add(person.ToString()); 
     } 
    } 

哪裏newCollection從UserCollection類在主窗口的形式創建新的對象。

我收到的錯誤:

foreach statement cannot operate on variables of type 'Collection.UserCollection' because 'Collection.UserCollection' does not contain a public definition for 'GetEnumerator' 

然後我試圖做一個小的解決方法,所以在我UserCollection我創建了以下方法:

 public User ReturnUser() 
    { 
     foreach (User person in _userCollection) 
     { 
      return person; 
     } 
     return null; 
    } 

(_userCollection是的名單<>用戶/會員在UserCollection.cs中)

然後像這樣使用它:

private void UpdatePeopleListings() 
    { 
     listViewPeople.Items.Add(newCollection.ReturnUser().ToString()); 
    } 

雖然這確實使用條目填充ListView,但它只填充第一個條目。 如果我要向newCollection添加多個用戶/成員,那麼它只是重複第一個條目。

我將如何去正確填充ListView與集合中的所有對象,以及如何防止它重複只有一個對象。

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 
      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 
} 

忽略任何隨機控制檯的東西,我沒有完成清理呢。

回答

3

foreach不起作用,因爲你的UserCollection類沒有實現IEnumerable接口。

ListItems不是你所期望的,因爲你不明白ListView/ListViewItems是如何工作的。 ListView由ListViewItems組成,ListViewItem可以由SubItems組成(僅在ListView的viewstyle設置爲'report'時顯示)。

當您使用您正在使用的方法添加ListViewItem時,僅定義了ListViewItem的'標題'。 這意味着,你將不得不使用Add方法的另一個重載;將ListViewItem對象作爲參數的方法。 然後,你可以這樣做:

ListViewItem item = new ListViewItem(); 
item.Text = "bar"; 
item.SubItems.Add ("foo"); 
item.SubItems.Add ("foo2"); 
myListView.Items.Add (item); 

在只有一個項目被添加到列表中的問題: - 你只添加一個項目...更具體地說,您要添加集合本身,而不是爲集合中的每個對象創建一個ListViewItem。

所以,你必須做的是:

  • 迭代在你的列表(使用的foreach(意味着你必須實現對集合類的IEnumerable),或使用一個for循環(但你必須確保您可以使用索引器訪問集合的內容))
  • 爲列表中存在的每個對象創建一個ListViewItem。

我想知道爲什麼你在第一個地方創建了自定義的UserCollection。我看到你已經實現了一些特定的功能,但是......我認爲有更好的解決方案。 儘管如此,您應該爲該類實現IEnumerable接口,IList接口等。通過這樣做,你的班級將成爲一個「真正的集合」,然後你可以像任何其他集合班一樣使用它。 (迭代使用foreach,或使用for循環,等等。)

+1

+1以上所有內容,還有一件事:考慮在'ListView'上使用'DataGridView'。 'DataGridView'可以直接綁定到集合,無需創建並同步項目。 – 2009-11-27 22:44:15

+0

工作正常,最初有一些問題,並非所有數據都不會顯示。我必須手動編碼以下屬性才能顯示所有項目和列: listViewPeople.View = View.Details; listViewPeople.FullRowSelect = true; listViewPeople.GridLines = true; 此外,有沒有辦法讓列表不會重新填充所有條目,每當我添加一個新的。我必須調用listViewPeople.Items.Clear();在添加所有項目之前,確保沒有數據重複。 – 2009-11-28 23:36:13

0

結合弗雷德裏克Gheysel的答案,這是明智的實施IEnumerator也。請記住在這樣做時覆蓋Equals,GetHashCode和ToString。