1

ピボットビューアーで 2 つのコレクション間の遷移を管理する方法を理解しようとしています。コレクションには同じ画像があります。1 つのコレクションが処理されるだけです。あるコレクションを別のコレクションに消したいです。

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>

私が採用できるこのような解決策はありますか?そのためのベストプラクティスは何ですか?

4

1 に答える 1

1

コレクション全体を置き換えるのではなく、読み込まれた 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
    }
}
  • コード化されたカスタム差分関数ですが、誰かがそれを行う素晴らしいライブラリを持っていると確信しています。
  • ファセット カテゴリの差分も追加することを考えましたが、そのために構築されていません。推奨される方法は、クライアントが利用可能なすべてのカテゴリを認識していることを確認して、それらをフィルタリングに使用できるようにすることだと思います。
于 2012-10-05T00:46:36.293 に答える