Oct 5 2006

Filter Collection of Objects

Category: ASP.NET 1.x | ASP.NET 2.0 - GeneralBil@l @ 06:04

I have been developing an API for an application of mine at work. The API returns a set of objects in the form of Collections. I needed a way to filter the collection based on some values I provide.

I have passed by this blog post:

http://codebetter.com/blogs/brendan.tompkins/archive/2004/09/02/24116.aspx

Brendan creates something known as CollectionView, that supports both Windows and Web collections.

I took that code, and did some modifications on it:

  1. I removed the IBindingList interface
  2. I removed all methods from the IList and ICollection implementation that might allow change of data in teh input Collection.
  3. I removed the sorting feature

I made the collection a normal collection that takes as input a collection, and then allows the developer to filter data inside.

In addition, I made the CollectionView capable of filtering not only on the direct properties of the classes inside the IList, but also multilevel properties as follows:

Currently, you can filter on simple data-types properties:

public string/int/double (etc ...) PropertyName
{
   get {}
   set {}
}

My CollectionView allows you to do filtering even on:

public Person MyPerson
{
    get {}
    set {}
}

Where Person is a class, so you can filter a collection of objects, where each object might have a property of type another object, i.e. you can filter a collection based on a property in the multilevel properties of the objects in the Collection.

An example illustrates how to use the new ApplyFilter method:

Suppose, a class Person has a property of type Address, where Address is another class that has a property called City as follows:

 

 public class Person
 {
  //members
  private string firstName=null;
  private string lastName=null;
  private Address address = null;
  
  //Public constructor
  public Person(string FirstName,string LastName, Address address)
  {
   this.firstName =FirstName;
   this.lastName=LastName;
   this.address = address;
  }

  #region Properties for member access
  public string FirstName
  {
   get
   {
    return firstName;
   }
   set
   {
    firstName=value;
   }
  }

  public string LastName
  {
   get
   {
    return lastName;
   }
   set
   {
    lastName=value;
   }
  }

  public Address Address
  {
   get
   {
    return this.address;
   }
   set
   {
    this.address=value;
   }
  }

  #endregion
 }
}


 public class Address
 {
  private string city;

  public string City
  {
   get
   {
    return this.city;
   }
   set
   {
    this.city = value;
   }
  }

  public Address(string City)
  {
   this.city = City;
  }
 }

Now you create a collection of Person class as follows:

PersonCollection pCol = new PersonCollection();
Person p1 = new Person("Bilal", "Haidar", new Address("Beirut"));
Person p2 = new Person("Lara", "Keyrouz", new Address("Beirut"));
Person p3 = new Person("Wessam", "Zeidan", new Address("Zahle"));
Person p4 = new Person("Ziad", "Hanna", new Address("Beirut"));
Person p5 = new Person("Alaa", "Said", new Address("Saida"));

Now, you want to get all persons in Beirut, which is a property called City inside object Address, where Address is a property inside Person class, so you can see the hierarchy:

Person
   --------> Address
                       --------> City

What you do is use the new ApplyFilter method as follows:

CollectionView cv = new CollectionView(pCol);
cv.ApplyFilter("Address","City", new Object[] {"Beirut"},FilterOperand.Equals);

The first parameter in the ApplyFilter is the Property, the second is the SubProperty, then an array of objects to provide the data in where to search, then an operand of equals.

You can even search for direct and simple properties as follows:

CollectionView cv = new CollectionView(pCol);
cv.ApplyFilter("FirstName",null, new Object[] {"Bilal"},FilterOperand.Equals);

I have also added a new Filter Option called "InRange", this way, you can search for a set of values as follows:

CollectionView cv = new CollectionView(pCol);
cv.ApplyFilter("FirstName",null, new Object[] {"Bilal", "Wessam"},FilterOperand.InRange);

This way, it will bring you person records whose FirstName are in a set of values (Bilal and Wessam).

The additions are:

  1. Support for multilevel property filter
  2. A new Filter Operan called InRange has been added
  3. Data to be filtered according to has been changed to an array of Objects

You can download the CollectionView.cs file and use it in your applications.

I will be enhancing it with sort option, maybe more Filter Operands too!!

Hope you liked this post!!

Regards

 

Tags: ,