コレクション全体を置き換えるのではなく、読み込まれた CXML コレクション間の重複を維持する例を次に示します。オブジェクトの追加と削除時にアニメーションがあるので、かなり見栄えがします。サーバー/バックエンドからさらに/部分的なデータを要求する場合に役立ちます。(もちろん、これはズーム時に「コレクション/アイテムがフェードする」こととは何の関係もありません。)
最も興味深いコードはKeepIntersection(this ICollection<PivotViewerItem> currentItems, CxmlCollectionSource newItems)
、古いコレクションと新しいコレクションの違いのみを追加および削除することによってコレクションを変更する にあります。
Tony ChampionsおよびChris Arnoldのチュートリアル/投稿ObservableCollection
によるSilverlight 5 PivotViewer に基づいています。
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
}
}
- コード化されたカスタム差分関数ですが、誰かがそれを行う素晴らしいライブラリを持っていると確信しています。
- ファセット カテゴリの差分も追加することを考えましたが、そのために構築されていません。推奨される方法は、クライアントが利用可能なすべてのカテゴリを認識していることを確認して、それらをフィルタリングに使用できるようにすることだと思います。