这是一个在加载的 CXML 集合之间保持重叠而不是替换整个集合的示例。由于添加和删除对象时有动画,它看起来很不错。从服务器/后端请求更多/部分数据时很有用。(当然,这与缩放时“褪色的集合/项目”无关。)
最有趣的代码是 in KeepIntersection(this ICollection<PivotViewerItem> currentItems, CxmlCollectionSource newItems)
,它通过仅添加和删除旧集合和新集合的差异来修改集合。
ObservableCollection
根据Tony Champions和Chris Arnold的教程/帖子,基于 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
}
}
- 编码的自定义差异函数,但我确信有人有一个很棒的库可以做到这一点。
- 也考虑为方面类别添加差异,但它不是为此而构建的。我想推荐的方法是确保客户端知道所有可用的类别,以便它们可以用于过滤。