• panorama控件平滑跳转到指定的item


    panorama控件是wp中最有特色的控件之一,它提供了wp独有的全景视图,但是在使用该控件的时候,我碰到了这么一个问题。我想在代码中指定panorama的SelectedIndex,但是该属性是只读的,通过在网上寻找,最终还是没有找到一个完美的解决方案,网上的解决方案大抵如下:

    1.使用panorama.DefaultItem=panorama.Items[newIndex];

    这个方法它只是将第index处的item放到了第一个位置,而且没有过渡的动画,不符合要求。

    2.通过设置SelectedItemProperty这个依赖属性来改变SelectedItem的值。

    panorama.SetValue(Panorama.SelectedItemProperty, pan.Items[newIndex]);
    

    但是就算这么设了,还是没有滑动的动画效果,具体请参考网友提供的代码

    为了得到一个完美的解决方案,楼主深入挖掘了panorama控件的动画运作方式以及它的控件模板。最终搞定了这个问题,代码比较多。下面是主要的一个函数

            /// <summary>
            /// 平滑过渡到指定的Item
            /// </summary>
            /// <param name="panorama"></param>
            /// <param name="index">指定的Item索引</param>
            /// <param name="duration">动画时长</param>
            /// <param name="complated">动画完成后需要执行的动作</param>
            public static void GoTo(this Panorama panorama, int index, Duration duration, Action complated = null)
            {
                if (panorama.Items.Count == 0)
                    return;
                while (index < 0)
                    index += panorama.Items.Count;
                while (index >= panorama.Items.Count)
                    index -= panorama.Items.Count;
                if (index == panorama.SelectedIndex)
                    return;
    
                var bgLayer = panorama.Descendants<PanningBackgroundLayer>().FirstOrDefault();
                var titleLayer = panorama.Descendants<PanningTitleLayer>().FirstOrDefault();
                var itemsLayer = panorama.Descendants<PanningLayer>().LastOrDefault();
                var panel = panorama.Descendants<PanoramaPanel>().FirstOrDefault();
                if (panel == null)
                    return;
    
                var direction = -1;
                if (index > panorama.SelectedIndex)
                {
                    var length1 = index - panorama.SelectedIndex;
                    var length2 = panorama.Items.Count - length1;
                    if (length2 < length1)
                        direction = 1;
                }
                else
                {
                    var length1 = panorama.SelectedIndex - index;
                    var length2 = panorama.Items.Count - length1;
                    if (length1 <= length2)
                        direction = 1;
                }
    
                var currentOffset = -GetOffsetX(panel, panorama.SelectedIndex);
                var offset = -(int) GetOffsetX(panel, index);
                if (Math.Sign(offset - currentOffset) != Math.Sign(direction))
                {
                    if (bgLayer != null)
                        bgLayer.Wraparound(direction);
                    if (titleLayer != null)
                        titleLayer.Wraparound(direction);
                    if (itemsLayer != null)
                        itemsLayer.Wraparound(direction);
                }
                panorama.SetValue(Panorama.SelectedItemProperty, panorama.Items[index]);
                UpdateItemPositions(panorama, panel);
                if (bgLayer != null)
                    bgLayer.GoTo(offset, duration, null);
                if (titleLayer != null)
                    titleLayer.GoTo(offset, duration, null);
                if (itemsLayer != null)
                    itemsLayer.GoTo(offset, duration, complated);
            }
    

    当想以动画形式过渡到某个项时,直接如下使用即可:

    panorama.GoTo(0, new Duration(TimeSpan.FromMilliseconds(800)));
    

    为了实现最终的目的,还必须的用到LinqToTree这个利器。

    全部的代码可以在此处下载:http://vdisk.weibo.com/s/yVSnUWjPhIz8j

     注意:wp8中PanningLayer的GoTo函数只有两个参数,只需要将下面几行代码更改一下即可使用

    if (bgLayer != null)
        bgLayer.GoTo(offset, duration, null);
     if (titleLayer != null)
        titleLayer.GoTo(offset, duration, null);
     if (itemsLayer != null)
       itemsLayer.GoTo(offset, duration, complated);
    

     改为:

                if (bgLayer != null)
                    bgLayer.GoTo(offset, duration);
                if (titleLayer != null)
                    titleLayer.GoTo(offset, duration);
                if (itemsLayer != null)
                    itemsLayer.GoTo(offset, duration);
                if (complated == null) 
                    return;
                var timer = new DispatcherTimer {Interval = duration.TimeSpan};
                timer.Tick += (sender, e) =>
                    {
                        complated();
                        timer.Stop(); 
                    };
                timer.Start();
  • 相关阅读:
    hibernate hql
    数据库锁机制
    Spring 事物管理
    spring自动代理
    spring 其它增强类型
    spring
    mybatis动态sql
    SSH注解整合
    ssh整合
    错题解析
  • 原文地址:https://www.cnblogs.com/chenxx08/p/2955570.html
Copyright © 2020-2023  润新知