CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Apr 2013
    Posts
    11

    Using List<> with a ListBox

    Hello. I'm trying to create a form called MainForm that contains a ListBox with the ability to add, edit and remove objects from the list. The list shows strings with data coming from a List<Customer> called CustomerList. My problem lies in editing and removing items from the list. When an item is removed from the listbox, the index for the next item moves down. This doesn't apply to object lists, which ends up with an exception. For example, imagine we have the following:

    ListBox:
    Customer1 - index = 0
    Customer2 - index = 1
    Customer3 - index = 2

    CustomerList:
    Customer1 - index = 0
    Customer2 - index = 1
    Customer3 - index = 2

    Now, we decide to remove Customer2 from both lists, it'll turn into this:

    ListBox:
    Customer1 - index = 0
    Customer3 - index = 1

    CustomerList:
    Customer1 - index = 0
    Customer2 - index = null
    Customer3 - index = 2

    How do I go around this without using Linq or any other sort of magic?

    Help's very much appreciated!

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Using List<> with a ListBox

    Not sure how you are doing this, but why not bind the List<> to the listbox? When you delete or add and item to the list, rebind it.

  3. #3
    Join Date
    Apr 2013
    Posts
    11

    Re: Using List<> with a ListBox

    How do I bind the list to the listbox while still having a convenient string to use when adding to the listbox?

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Using List<> with a ListBox

    What do you mean, "convenient string to use"?

    As I mentioned, you will always add/remove items from the list (not the listbox) and rebind.

  5. #5
    Join Date
    Apr 2013
    Posts
    11

    Re: Using List<> with a ListBox

    Quote Originally Posted by Arjay View Post
    What do you mean, "convenient string to use"?
    Sorry for being unclear. My assignment apperantly says I cannot use datasource but have to add them by hand.

  6. #6
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Using List<> with a ListBox

    Too bad you are being taught an old-fashioned way of doing this.

    At any rate, when you remove an item from the listbox, remove the same item from the List<>.

    Something like this...

    Code:
    private void _removeButton_Click(object sender, EventArgs e)
    {
                if (_customerListBox.SelectedIndex != InvalidIndex)
                {
                    _customers.RemoveAt(_customerListBox.SelectedIndex); // remove the item from the list
    
                    _customerListBox.Items.RemoveAt(_customerListBox.SelectedIndex); // remove the item from the listbox
    
                }
    }
    Note: InvalidIndex is an int const defined as -1

  7. #7
    Join Date
    Apr 2013
    Posts
    11

    Re: Using List<> with a ListBox

    Yeah, I thought of that. But it doesn't solve the problem that arises when you try to remove the list item after the first removed one.
    ListBoxes rearrange themselves so the order is always 0, 1, 2, 3.. while Lists do not.
    Last edited by sadslapper; May 1st, 2013 at 04:35 PM.

  8. #8
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Using List<> with a ListBox

    Quote Originally Posted by sadslapper View Post
    Yeah, I thought of that. But it doesn't solve the problem that arises when you try to remove the list item after the first removed one.
    ListBoxes rearrange themselves so the order is always 0, 1, 2, 3.. while Lists do not.
    No they don't - unless you have the sort style set. And if you do, just resort the List<> after inserting a new item - that way, the indexes will always match.

  9. #9
    Join Date
    Apr 2013
    Posts
    11

    Re: Using List<> with a ListBox

    How do I change the sort style? I can't find anything about it on MSDN. Also, I tried to resort it, but I got this error message when I tried to remove an item between two other items:

    System.InvalidOperationException: Jämförelsen av två element i matrisen misslyckades. ---> System.ArgumentException: Minst ett objekt måste implementera IComparable.
    vid System.Collections.Comparer.Compare(Object a, Object b)
    vid System.Collections.Generic.ObjectComparer`1.Compare(T x, T y)
    vid System.Collections.Generic.ArraySortHelper`1.SwapIfGreater(T[] keys, IComparer`1 comparer, Int32 a, Int32 b)
    vid System.Collections.Generic.ArraySortHelper`1.IntroSort(T[] keys, Int32 lo, Int32 hi, Int32 depthLimit, IComparer`1 comparer)
    vid System.Collections.Generic.ArraySortHelper`1.IntrospectiveSort(T[] keys, Int32 left, Int32 length, IComparer`1 comparer)
    vid System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
    --- End of inner exception stack trace ---
    vid System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
    vid System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer`1 comparer)
    vid System.Collections.Generic.List`1.Sort(Int32 index, Int32 count, IComparer`1 comparer)
    vid System.Collections.Generic.List`1.Sort()
    vid assignment_5.MainForm.RemoveBtnClick(Object sender, EventArgs e) i c:\Users\Krogen\Documents\SharpDevelop Projects\assignment_5\assignment_5\MainForm.cs:rad 74
    vid System.Windows.Forms.Control.OnClick(EventArgs e)
    vid System.Windows.Forms.Button.OnClick(EventArgs e)
    vid System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
    vid System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    vid System.Windows.Forms.Control.WndProc(Message& m)
    vid System.Windows.Forms.ButtonBase.WndProc(Message& m)
    vid System.Windows.Forms.Button.WndProc(Message& m)
    vid System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    vid System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    vid System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    vid System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    vid System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
    vid System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    vid System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    vid System.Windows.Forms.Application.Run(Form mainForm)
    vid assignment_5.Program.Main(String[] args) i c:\Users\Krogen\Documents\SharpDevelop Projects\assignment_5\assignment_5\Program.cs:rad 19

    This line:
    System.InvalidOperationException: Jämförelsen av två element i matrisen misslyckades. ---> System.ArgumentException: Minst ett objekt måste implementera IComparable.

    Means 'The comparison of two elements in the matrix failed. ---> At least one object must implement IComparable.'

  10. #10
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Using List<> with a ListBox

    You can change the sort style of the listbox, by opening the main form in the design view, right click on the list box and choose "Properties".

    In the properties window, scroll down until you find the Sorted property and set it to False.

  11. #11
    Join Date
    Apr 2013
    Posts
    11

    Re: Using List<> with a ListBox

    It had been on sort = false the whole time, changing it to true didn't change anything. Here are my methods:

    Code:
    	public class CustomerManager
    	{
    		private List<Customer> m_customers;
    		
    		public List<Customer> CustomerList
    		{
    			get {return m_customers;} 
    			
    			set {m_customers = value;}
    		}
    
    **Other stuff**
    
    
    Back in MainForm:
    
    		private void NewListItem()
    		{
    			string customerString = string.Format("\t{0}", m_contact.FinalString);
    			customerList.Items.Add(customerString);
    			
    			m_manager.AddCustomer();
    		}
    
    		public void EditCustomer()
    		{
    			m_manager.CustomerList[id].ContactData.FirstName = m_contact.ContactData.FirstName;
    			m_manager.CustomerList[id].ContactData.LastName = m_contact.ContactData.LastName;
    			m_manager.CustomerList[id].ContactData.AdressData.City = m_contact.ContactData.AdressData.City;
    			m_manager.CustomerList[id].ContactData.AdressData.Country = m_contact.ContactData.AdressData.Country; 
    			m_manager.CustomerList[id].ContactData.AdressData.Street = m_contact.ContactData.AdressData.Street;
    			m_manager.CustomerList[id].ContactData.AdressData.Zipcode = m_contact.ContactData.AdressData.Zipcode;
    			m_manager.CustomerList[id].ContactData.PhoneData.Work = m_contact.ContactData.PhoneData.Work;
    			m_manager.CustomerList[id].ContactData.PhoneData.Home = m_contact.ContactData.PhoneData.Home;
    			m_manager.CustomerList[id].ContactData.EmailData.Work = m_contact.ContactData.EmailData.Work;
    			m_manager.CustomerList[id].ContactData.EmailData.Personal = m_contact.ContactData.EmailData.Personal;		
    		}
    		
    		void AddBtnClick(object sender, EventArgs e)
    		{
    			id = customerList.SelectedIndex;
    			m_contact = new ContactForm();
    			m_contact.FormFilled = false;
    			m_contact.ShowDialog();
    			
    			if (m_contact.FormFilled == true) 
    			{
    				NewListItem();
    			}
    		}
    		
    		void RemoveBtnClick(object sender, EventArgs e)
    		{
    			id = customerList.SelectedIndex;
    			customerList.Items.RemoveAt(id);
    			m_manager.RemoveCustomer(id);	
    		}
    		
    		void EditBtnClick(object sender, EventArgs e)
    		{
    			id = customerList.SelectedIndex;
    			
    			if (id >= 0) 
    			{
    				EditCustomer();
    				m_contact.FormFilled = false;
    				m_contact.LoadValues();
    				m_contact.ShowDialog();
    				
    				if (m_contact.FormFilled == true)
    					{
    						customerList.Items.RemoveAt(id);
    						NewListItem();
    					}
    			}
    			
    			else
    				NothingSelected();
    		}
    Last edited by Arjay; May 2nd, 2013 at 05:20 PM. Reason: Added code tags

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured