1

I have a BindingList with objects in which is saved some contacts.

 internal static BindingList<object> contactList;

The contactList object is more types. SktContact, FBContact, GContact.

These contacts I add in contactList_Changed event to listBox. But I want sort them by status (first online) and then alphabetically.

I would like somethink like this:

  List<object> contactSorted = new List<object>();
  contactSorted = Global.contactList.ToList();

  contactSorted.OrderBy((status, name) => Converter.getContactAvailabilityStatus(contactSorted[?]), Converter.getContactName(contactSorted[?]));

  contactListBox.Items.AddRange(contactSorted.ToArray());

But I dont have any idea how shoud I do that. I cannot retype the list of objects and select the property to order by.

I have methods to get status and name from any object. But how can I use it to sort the contact array?

I'm using own drawing Owner draw fixed

 private void contactListBox_DrawItem(object sender, DrawItemEventArgs e)
sczdavos
  • 2,035
  • 11
  • 37
  • 71
  • 2
    Just to clarify, can't you implement a common interface for your Contact classes, something like IContact with name and status as properties? – M. Mennan Kara Aug 17 '12 at 14:39
  • If it is necessary I'll do that, but I have that object in listBox and if I click on any of them I check what kind of object is that and appropriate client is using it. Fxp if I choose Skype contact I retype it and using with methods in SkypeKit. – sczdavos Aug 17 '12 at 14:44
  • Not enough information to write it for you. But a base type ContactBase) or Interface (IContact) instead of Object would be good, and then use SortedList, or SortedList(ContactBase) with a Comparer would be a better way to go. – Tony Hopkinson Aug 17 '12 at 14:45

2 Answers2

3
  1. It feels like you could use an interface for the contact type:

    interface IContact
    {
        string Status { get; }
        string Name { get; }
    }
    
    class FBContact : IContact
    {
        public string Status
        {
            get
            {
                // Implement the status getter   
            }
        }
        public string Name
        {
            get
            {
                // Implement the contact name getter   
            }
        }
    } 
    
  2. Then just

    var unsortedList = Global.contactList;
    var contactSorted = unsortedList.Cast<IContact>()
                                    .OrderBy(x => x.Status)
                                    .ThenBy(x => x.Name);
    
    contactListBox.Items.AddRange(contactSorted.ToArray());
    
twoflower
  • 6,788
  • 2
  • 33
  • 44
2

What you can do is to implement an interface for your contact classes.

public interface IContact{
    string Name {get;set;}
    int Status{get;set;}
}

And change your class declarations as

public class SktContact: IContact {
    // Implementations
}
...

After that you can declare your list with the interface name

var contacts= new List<IContact>():
// Populate contacts to the list

Then order the list as

var orderedList = contact.OrderByDescending(c=>c.Status).ThenBy(c=>c.name).ToList():

Then while using the list items you can use GetType() method to determine their types and use the appropriate code to handle them.

In case if you don't have access to the implementations of the contact classes you can use Adapter Design Pattern to make them compatible with your code.

M. Mennan Kara
  • 10,072
  • 2
  • 35
  • 39