Click here to Skip to main content
15,844,155 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
Hallo All

I have this ObservableCollectionEx class.
Basically, all I want from it is to extend the INotifyPropertyChanged event to any changes on any member of the collection.

ObservableCollectionEx Class
C#
public partial class ObservableCollectionEx<T> : ObservableCollection<T>
    where T : INotifyPropertyChanged
{
    public ObservableCollectionEx() : base() { }

    public ObservableCollectionEx(List<T> list)
        : base((list != null) ? new List<T>(list.Count) : list)
    {
        CopyFrom(list);
    }

    public ObservableCollectionEx(IEnumerable<T> collection)
    {
        if (collection == null)
            throw new ArgumentNullException("collection");
        CopyFrom(collection);
    }

    private void CopyFrom(IEnumerable<T> collection)
    {
        IList<T> items = Items;
        if (collection != null && items != null)
        {
            using (IEnumerator<T> enumerator = collection.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    items.Add(enumerator.Current);
                }
            }
        }
    }

    protected override void InsertItem(int index, T item)
    {
        base.InsertItem(index, item);
        item.PropertyChanged += Item_PropertyChanged;
    }

    protected override void RemoveItem(int index)
    {
        Items[index].PropertyChanged -= Item_PropertyChanged;
        base.RemoveItem(index);
    }

    protected virtual void MoveItem(int oldIndex, int newIndex)
    {
        T removedItem = this[oldIndex];
        base.RemoveItem(oldIndex);
        base.InsertItem(newIndex, removedItem);
    }

    protected override void ClearItems()
    {
        foreach (T item in Items)
        {
            item.PropertyChanged -= Item_PropertyChanged;
        }
        base.ClearItems();
    }

    protected override void SetItem(int index, T item)
    {
        T oldItem = Items[index];
        T newItem = item;
        oldItem.PropertyChanged -= Item_PropertyChanged;
        newItem.PropertyChanged += Item_PropertyChanged;
        base.SetItem(index, item);
    }

    private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        var handler = ItemPropertyChanged;
        if (handler != null) { handler(sender, e); }
    }

    public event PropertyChangedEventHandler ItemPropertyChanged;
}


Additionally I have an extension to the ObservableCollection class, a simple ToObservableCollection() method.

CollectionExtensions - ToObservableCollection()
C#
public static class CollectionExtensions
{
    public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> enumerableList)
    {
        return enumerableList != null ? new ObservableCollection<T>(enumerableList) : null;
    }
}


As I needed the ToObservableCollectionEx(), I build it the same way I did to the ToObservableCollection.

C#
public static ObservableCollectionEx<T> ToObservableCollectionEx<T>(this IEnumerable<T> enumerableList)
{
    return enumerableList != null ? new ObservableCollectionEx<T>(enumerableList) : null;
}


But I get this error:
"The type 'T' cannot be used as type parameter 'T' in the generic type or method 'Portal_Tools.ObservableCollectionEx<t>'. There is no boxing conversion or type parameter conversion from 'T' to 'System.ComponentModel.INotifyPropertyChanged'."

Googled around this message and couldn't find any answer that would solve this error.

Tried different approaches but always got the same error because the <T> is always there.

Can anyone help me out and give me a clue on how to solve this error?

Thanks
Posted
Updated 22-Sep-13 13:10pm
v3
Comments
BillWoodruff 23-Sep-13 3:53am    
That's very interesting code, and perhaps, in the future, you might consider writing an article about what you're doing here, and why you are doing it ?

I'm wondering what type of real-world scenario would require this type of facility, although the uses for INotifyPropertyChanged are obvious. Application logging, access logging, come to mind.

thanks, Bill
Jorge J. Martins 28-Sep-13 11:00am    
Hi Bill

Promiss I'll write that article soon on how I use this ObservableCollectionEx!

My need of this solution is related to DependencyProperties Binding, Value Converters and Lambda Expressions and it's being used on several parts of this project for diferent needs.

I'll use one of this parts as an example on that article.

Thanks
Jorge
Jorge J. Martins 30-Sep-13 4:12am    
Here it is:
http://www.codeproject.com/Articles/660423/ObservableCollection-notification-on-member-change

1 solution

I have figured it out! It's working.
C#
        public static ObservableCollectionEx<t> ToObservableCollectionEx<t>(this IEnumerable<t> enumerableList) where T : INotifyPropertyChanged
        {
            return enumerableList != null ? new ObservableCollectionEx<t>(enumerableList) : null;
        }
</t></t></t></t>


The difference is on the where T : INotifyPropertyChanged part.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900