1

I'm trying to understand how to manage a transition between two collections in pivotviewer. Collections have the same images, it's just that one collection is processed. I want to have one collection vanishing into the other.

I know how to define different templates that vanishes one into the other by fixing the maxwidth. For example once you zoom over 300 px then you have your new template until you reach 500 px, etc. The code I use to bind the collection I've loaded in the code behind is like this:

<pv:PivotViewerItemTemplate x:Key="firstTemplate" MaxWidth="300">
    <!-- template layout -->
    <pv:PivotViewerMultiScaleSubImageHost CollectionSource="{Binding [VisualCollectionSource][0] }"  ImageId="{Binding [VisualImageId][0]}" />
    <!-- template layout -->
</pv:PivotViewerItemTemplate>

Is there a solution like this I can adopt? What's the best practice for it?

Community
  • 1
  • 1
sparaflAsh
  • 646
  • 1
  • 9
  • 26
  • Do you mean that one collection should *vanish (fade?) into* another collection when zooming in, or that you want to *load* another collection sometime after the first one has been loaded? – Joel Purra Sep 13 '12 at 19:14
  • Yes, the first option is exactly the effect I would like to get. – sparaflAsh Sep 14 '12 at 20:16
  • Havent implemented changing the collection when zooming, only dynamically replacing collections that have some overlapping item. For the second option, it's quite easy to work with [`ObservableCollection`](https://www.google.com/?q=pivotviewer+observablecollection) as per [Tony Champions's](http://tonychampion.net/blog/index.php/category/silverlight/pivotviewer-silverlight/) and [Chris Arnold's](http://goodcoffeegoodcode.wordpress.com/category/technology/programming/silverlight/pivotviewer/) tutorials/posts. – Joel Purra Sep 14 '12 at 20:30
  • Thank you, I knew those two blogs. They are very useful. Hope someone comes up with some idea. – sparaflAsh Sep 20 '12 at 07:33
  • Actually I was trying to load another collection as you suggested, but I can't help to succeed. For what I need actually this solution will work. Can you please provide as answer an easy example? – sparaflAsh Oct 02 '12 at 07:55

1 Answers1

1

Here's an example of keeping the overlap between loaded CXML collections, instead of replacing the entire collection. Since there are animations when adding and removing objects, it looks pretty nice. Useful when requesting more/partial data from the server/backend. (Of course, this has nothing to do with "fading collections/items" when zooming.)

The most interesting code would be in KeepIntersection(this ICollection<PivotViewerItem> currentItems, CxmlCollectionSource newItems), which modifies the collection by adding and removing only the differences from the old and the new collections.

Based on Silverlight 5 PivotViewer's ObservableCollection as per Tony Champions's and Chris Arnold's tutorials/posts.

MainPageViewModel.cs

private void CxmlCollectionSource_StateChanged(object sender, CxmlCollectionStateChangedEventArgs e)
{
    // TODO: check other states
    switch (e.NewState)
    {
        case CxmlCollectionState.Loaded:
            {
                var collection = sender as CxmlCollectionSource;

                Debug.Assert(collection != null, "collection != null");

                // TODO: don't add/remove, replace the entire list after diffing
                if (!this.pivotProperties.Any())
                {
                    // TODO: diffing algorithm for properties, minimal changes
                    foreach (var pivotViewerProperty in collection.ItemProperties)
                    {
                        this.pivotProperties.Add(pivotViewerProperty);
                    }
                }

                this.pivotViewerItems.KeepIntersection(collection);

                break;
            }
    }
}

ICollection{PivotViewerItem}Extensions.cs

namespace SilverlightPivotViewer.Extensions
{
    #region Using directives

    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Controls.Pivot;

    #endregion

    public static class ICollectionPivotViewerItemExtensions
    {
        #region Public Methods and Operators

        public static void KeepIntersection(
            this ICollection<PivotViewerItem> currentItems, CxmlCollectionSource newItems)
        {
            RemoveCurrentUniqueItems(currentItems, newItems);

            AddNewUniqueItems(currentItems, newItems);
        }

        #endregion

        #region Methods

        private static void AddNewUniqueItems(ICollection<PivotViewerItem> currentItems, CxmlCollectionSource newItems)
        {
            IEnumerable<PivotViewerItem> onlyInNewCollection =
                newItems.Items.Where(pivotViewerItem => currentItems.All(i => i.Id != pivotViewerItem.Id));

            foreach (var pivotViewerItem in onlyInNewCollection)
            {
                currentItems.Add(pivotViewerItem);
            }
        }

        private static void RemoveCurrentUniqueItems(
            ICollection<PivotViewerItem> currentItems, CxmlCollectionSource newItems)
        {
            IEnumerable<PivotViewerItem> onlyInCurrentCollection =
                currentItems.Where(pivotViewerItem => newItems.Items.All(i => i.Id != pivotViewerItem.Id));

            // Need to produce a list, otherwise it will crash (concurrent looping and editing the IEnumerable, or something related)
            var onlyInCurrentCollectionList = onlyInCurrentCollection.ToList();

            foreach (var pivotViewerItem in onlyInCurrentCollectionList)
            {
                currentItems.Remove(pivotViewerItem);
            }
        }

        #endregion
    }
}
  • Coded custom diffing functions, but I'm sure someone has an awesome library doing just that.
  • Thought of adding diffing for facet categories too, but it's not built for it. I guess the recommended way is to make sure the client knows about all available categories, so they can be used for filtering.
Joel Purra
  • 24,294
  • 8
  • 60
  • 60