Reputation: 656
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?
Upvotes: 1
Views: 418
Reputation: 25167
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.
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;
}
}
}
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
}
}
Upvotes: 1