Skip to content

IListSource.ContainsListCollection explained


Whenever you implement own datasource for .NET GUI binding, you’lll have the choice – whether to implement IList or IListSource.

IListSource is a simplistic interface with two members: IList<T> GetList() and bool ContainsListCollection;

MSDN help about IListSource.ContainsListCollection states it’s “indicating whether the collection is a collection of IList objects”.
MSDN is not true here.

If IListSource.ContainsListCollection is false, GetList() just returns your IList.

If IListSource.ContainsListCollection is true, GetList() is expected to return ITypedList, which needs to provide a collection of PropertyDescriptor-s for every field of your collection.
Its purpose is to provide field names (including by-name field access) in runtime.

Quoted below is a code piece from a Microsoft newsgroup that resolves both cases to a data list (field values list, in second case).

And yes, if you’re planning to mutate the UI-bound collection, use IBindingList<> instead of IList<>.

static IEnumerable GetResolvedDataSource(object dataSource, string dataMember)
{
    if (dataSource != null)

    {
        IListSource source1 = dataSource as IListSource;
        if (source1 != null)

        {
            IList list1 = source1.GetList();
            if (!source1.ContainsListCollection)

            {
                return list1;
            }
            if ((list1 != null) && (list1 is ITypedList))

            {
                ITypedList list2 = (ITypedList) list1;
                PropertyDescriptorCollection collection1 = list2.GetItemProperties(new PropertyDescriptor[0]);

                if ((collection1 == null) || (collection1.Count == 0))

                {
                    throw new HttpException(HttpRuntime.FormatResourceString("ListSource_Without_DataMembers"));

                }
                PropertyDescriptor descriptor1 = null;
                if ((dataMember == null) || (dataMember.Length == 0))

                {
                    descriptor1 = collection1[0];
                }
                else

                {
                    descriptor1 = collection1.Find(dataMember, true);
                }

                if (descriptor1 != null)
                {
                    object obj1 = list1[0];

                    object obj2 = descriptor1.GetValue(obj1);
                    if ((obj2 != null) && (obj2 is IEnumerable))

                    {
                        return (IEnumerable) obj2;
                    }
                }

                throw new HttpException(HttpRuntime.FormatResourceString("ListSource_Missing_DataMember", dataMember));

            }
        }
        if (dataSource is IEnumerable)
        {
            return (IEnumerable) dataSource;

        }
    }
    return null;
}

2 Comments

  1. José Luis wrote:

    Hi victor.

    I have got a question about this issue.

    I have implemented a datasource control that usually returns false on ContainsListCollection() calls. Everything works fine here.

    But i want to make a datasource control with more than one list inside, so i changed my implementation, and i return true on ContainsListCollection() calls. So I tried to implement my getList() method to returning a BindingList of my original datasource items, but it seems it doesn’t work.

    Can you help me to show the way to do it?

    Regards

    Posted on 02-Jan-09 at 17:58 | Permalink
  2. Hi José.
    As far as I see from my experience, MSDN lies in that paragraph.
    Or, at least, there are different Controls that treat ContainsListCollection() in totally different senses.

    Particularly, for me (in DevExpress controls) ContainsListCollection() only meant that GetList() returns an ITypedList.

    Now, what do you mean saying “control with more than one list inside”, a grid-like control where each line item is another IList, or just two collections, or what?
    If so, you’ll need a specific Binding for each line anyway.
    And you’ll need to return such a PropertyDescriptor that describes how to bind your ITypedList‘s elements.

    Posted on 05-Jan-09 at 15:16 | Permalink

Post a Comment

Your email is never published nor shared.