在数据透视图中绑定两个不同的Collection Source

时间:2012-08-30 08:33:54

标签: c# silverlight data-binding silverlight-5.0 pivotviewer

我正在尝试了解如何在pivotviewer中管理两个集合之间的转换。集合具有相同的图像,只是处理了一个集合。我希望有一个集合消失在另一个集合中。

我知道如何定义不同的模板,通过修复maxwidth来消除一个模板到另一个模板。例如,一旦你缩放超过300像素然后你有你的新模板,直到达到500像素,等等。我用来绑定我在后面的代码中加载的集合的代码是这样的:

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

我可以采用像this这样的解决方案吗?它的最佳实践是什么?

1 个答案:

答案 0 :(得分:1)

这是一个保持加载的CXML集合之间重叠的示例,而不是替换整个集合。由于添加和删除对象时有动画,因此看起来非常不错。从服务器/后端请求更多/部分数据时很有用。 (当然,这与缩放时的“淡化集合/项目”无关。)

最有趣的代码将在KeepIntersection(this ICollection<PivotViewerItem> currentItems, CxmlCollectionSource newItems)中,它通过添加和删除旧集合和新集合的差异来修改集合。

基于Silverlight 5 PivotViewer ObservableCollection根据Tony ChampionsChris Arnold的教程/帖子。

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
    }
}
  • 编码自定义差异函数,但我确信有人有一个很棒的库就可以了。
  • 考虑为facet类别添加diffing,但它不是为它构建的。我想推荐的方法是确保客户端知道所有可用的类别,因此可以用它们进行过滤。