Blog Home  Home Feed your aggregator (RSS 2.0)  
kevin Mocha - CollectionViewSource
Bookmarks collected from web.
 
 Monday, June 02, 2008

http://geekswithblogs.net/thibbard/archive/2008/05/20/wpf---collectionviewsource-that-updates-automatically.aspx

public class AutoRefreshCollectionViewSource : CollectionViewSource
{
    protected override void OnSourceChanged(object oldSource, object newSource)
    {
        if (oldSource != null)
        {
            SubscribeSourceEvents(oldSource, true);
        }

        if (newSource != null)
        {
            SubscribeSourceEvents(newSource, false);
        }

        base.OnSourceChanged(oldSource, newSource);
    }


    private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        bool refresh = false;
        foreach (SortDescription sort in SortDescriptions)
        {
            if (sort.PropertyName == e.PropertyName)
            {
                refresh = true;
                break;
            }
        }

        if (!refresh)
        {
            foreach (GroupDescription group in GroupDescriptions)
            {
                PropertyGroupDescription propertyGroup = group as PropertyGroupDescription;

                if (propertyGroup != null && propertyGroup.PropertyName == e.PropertyName)
                {
                    refresh = true;
                    break;
                }
            }
        }

        if (refresh)
        {
            View.Refresh();
        }
    }

    private void Source_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            SubscribeItemsEvents(e.NewItems, false);
        }

        else if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            SubscribeItemsEvents(e.OldItems, true);
        }
        else
        {
            // TODO: Support this
            Debug.Assert(false);
        }
    }

     
    private void SubscribeItemEvents(object item, bool remove)
    {
        INotifyPropertyChanged notify = item as INotifyPropertyChanged;     

        if (notify != null)
        {
            if (remove)
            {
                notify.PropertyChanged -= Item_PropertyChanged;
            }
            else
            {
                notify.PropertyChanged += Item_PropertyChanged;
            }
        }
    }
     
    private void SubscribeItemsEvents(IEnumerable items, bool remove)
    {
        foreach (object item in items)
        {
            SubscribeItemEvents(item, remove);
        }
    }

    private void SubscribeSourceEvents(object source, bool remove)
    {
        INotifyCollectionChanged notify = source as INotifyCollectionChanged;

        if (notify != null)
        {
            if (remove)
            {
                notify.CollectionChanged -= Source_CollectionChanged;
            }

            else
            {
                notify.CollectionChanged += Source_CollectionChanged;
            }
        }

         
        SubscribeItemsEvents((IEnumerable)source, remove);

    }

}

Using the CollectionViewSource is a good way of binding to a datasource and letting the XAML determine the sorting and grouping of the data. However, as your datasource changes, the grouping and sorting is not automatically "re-calculated", forcing your code to be smarter that it should be. I found a class today on MSDN forums that inherits from CollectionViewSource and adds automatic refresh capabilities. This code is smart enough to resort your items, regroup your items and even add new groupings as needed.
Some good CollectionViewSource links:

Monday, June 02, 2008 7:49:01 PM UTC  #    Comments [0]    |  Trackback
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Copyright © 2008 Kevin Mocha. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.
Pick a theme: