2009-11-27 4 views
1

В настоящее время я конвертирую то, что было консольным приложением в приложение Windows Form. Fortunatly i изначально разработал приложение для работы с графическим интерфейсом в будущем, поэтому было не так много кода для изменения.Заполнение ListView объектами из списка <>

У меня есть класс UserCollection, который сам содержит список <> типа User/Member (Участник принадлежит пользователю).

Что я хотел бы сделать, это добавить каждый элемент в список UserCollection List <> в 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 установлен «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 для каждого объекта, находящегося в вашей коллекции.

Так что вы должны сделать, это:

  • итерации над списком (с использованием Еогеаспа (означает, что вы должны реализовать IEnumerable на классе коллекции), или с использованием для цикла (но вам придется убедитесь, что вы можете получить доступ к содержимому коллекции с помощью индексатора, например))
  • создать ListViewItem для каждого объекта, который существует в списке.

Интересно, почему вы создали свой заказ UserCollection в первую очередь. Я вижу, что вы реализовали некоторые конкретные функции, но ... Я думаю, что есть лучшие решения. Тем не менее вы должны реализовать интерфейс IEnumerable, интерфейс IList и т. Д. Для этого класса. Таким образом, ваш класс будет «реальной коллекцией», а затем вы сможете работать с ним, как и с любым другим классом коллекции. (Итерация с использованием foreach или с использованием цикла for и т. Д.)

+1

+1 всем перечисленным, и еще одна вещь: рассмотрите возможность использования DataGridView над ListView. 'DataGridView' может быть напрямую привязан к коллекциям, без необходимости создавать и затем синхронизировать элементы. –

+0

Прекрасно работает, изначально были проблемы, когда не все данные не показывались. Мне пришлось вручную ввести следующие свойства, чтобы отобразить все элементы и столбцы: listViewPeople.View = View.Details; listViewPeople.FullRowSelect = true; listViewPeople.GridLines = true; Кроме того, существует ли способ, чтобы список не был заселен всеми элементами всякий раз, когда я добавляю новый. Мне нужно вызвать listViewPeople.Items.Clear(); прежде чем я добавлю все элементы, чтобы гарантировать, что данные не будут повторяться. –

0

В сочетании с ответом Фредерика Гейзеля было бы целесообразно реализовать IEnumerator. При этом не забудьте переопределить Equals, GetHashCode и ToString.

Смежные вопросы