开发者

Pivot with many PivotItems

I'm developing a TV listing app for WP7, but I'm experiencing issues with the Pivot control: I tried at first to add all the available EPG channels, but performance are extremely poor (even on t开发者_开发问答he real phone), taking ~10-15sec to add 25 empty PivotItems, without any data or control.

So I tested a dynamic/lazy load oriented approach that loads only three items at first and then adds one more each time the user swipes left or right. Problem is, when swiping left the new item pushes the current one in the databound collection one slot to the right, producing a messy rendering on screen: that's not surprising, since SelectedIndex doesn't change, but selected item does. However, fixing SelectedIndex makes things even worse, resulting in Pivot to get stuck in an inconsistent layout.

Here's the code:

    public void ChangeChannel(){

        if (index < 0) return;
        int i = index;
        int tot = Epg.Channels.Count;
        int slack = (i == 0) ? -1 : i > oldIndex ? 1 : -1;

        var ch = this.Channels[i];
        var nextIndex = (ch.ChannelIndex + slack) % tot;
        if (nextIndex < 0) nextIndex += tot;

        var next = Epg.Channels[nextIndex];
        if (!this.Channels.Contains(next))
        {
            if (slack < 0)
            {
                this.Channels.Insert(0, next);
                //Index++;
            }
            else
                this.Channels.Add(next);
        }

        oldIndex = i;
    }

Method is associated to Pivot.LoadingPivotItem by means of Caliburn.Micro. index is bound to Pivot.SelectedIndex, Epg.Channels is the primary model object and this.Channels is an ObservableCollection bound to Pivot.ItemsSource

EDIT: Found the trick. I got suspicious when I recalled I have a RSS Reader app that has a Pivot with no less than 10-12 tabs working really fast. That said, I built a little test app working similarly but without using Caliburn. Oh, that's some performance! But is Caliburn so heavy? Not really, since I discovered this little piece of code in the default AppBootstrapper:

            ConventionManager.AddElementConvention<Pivot>(Pivot.ItemsSourceProperty, "SelectedItem", "SelectionChanged").ApplyBinding =
            (viewModelType, path, property, element, convention) =>
            {
                if (ConventionManager
                    .GetElementConvention(typeof(ItemsControl))
                    .ApplyBinding(viewModelType, path, property, element, convention))
                {
                    ConventionManager
                        .ConfigureSelectedItem(element, Pivot.SelectedItemProperty, viewModelType, path);
                    ConventionManager
                        .ApplyHeaderTemplate(element, Pivot.HeaderTemplateProperty, viewModelType);
                    return true;
                }

                return false;
            };

Removing it boosts performance, without having to quit Caliburn. Yeah, I know, that is something to investigate further, but for now it fixed all the stuff.


Anything above 5 items in a pivot is likely to have a noticabel performance impact.
Having the user trying to navigate between a large number of items is also likley to be very hard.

If you really need to use a pivot to show a large numebr of items you can do this by creating an instance with just 3 items in it and updating the bindings of each item as the selected item changes. The aim is to populate the items either side of the one that is currently displayed. The logic can get a bit messy (dependent upon the currently selected item and the previously displayed item, update the other binding) but it is do-able.


Consider using a custom handling of flicking left/right instead, and then just update the content as you go. With animations you can simulate transitions.

I've once created a comic reader this way. It's very easy, and doesn't impact performance.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜