zoukankan      html  css  js  c++  java
  • 代码滑动panorama-即程序中设置SelectedIndex

    我们都知道panorama的SelectedIndex属性是只读的,所以通过修改它,在程序滑动panorama似乎不可能。那么是不是就没有办法了呢?
    其实我们可以通过设置SelectedItemProperty这个依赖属性来改变SelectedItem的值。
    设置方法如下:

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

    虽然可以通过程序改变SelectedItem,但是panorama不会立即更新,我们只需要加一个小技巧,代码如下:

    (pan.Items[curIndex] as PanoramaItem).Visibility = Visibility.Collapsed;
    pan.SetValue(Panorama.SelectedItemProperty, pan.Items[(curIndex + 1) % pan.Items.Count]);
    pan.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
    (pan.Items[curIndex] as PanoramaItem).Visibility = Visibility.Visible;

    这样虽然实现了Item切换,却缺少动画效果,那么我们就需要找到相应的item控件,为其添加RenderTransform动画,即动画的target是RenderTransform。
    具体实现如下:
    private void slidePanorama(Panorama pan)
    {
        FrameworkElement panWrapper = VisualTreeHelper.GetChild(pan, 0) as FrameworkElement;
        FrameworkElement panTitle = VisualTreeHelper.GetChild(panWrapper, 1) as FrameworkElement;
        //Get the panorama layer to calculate all panorama items size
        FrameworkElement panLayer = VisualTreeHelper.GetChild(panWrapper, 2) as FrameworkElement;
        //Get the title presenter to calculate the title size
        FrameworkElement panTitlePresenter = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(panTitle, 0) as FrameworkElement, 1) as FrameworkElement;
     
        //Current panorama item index
        int curIndex = pan.SelectedIndex;
     
        //Get the next of next panorama item
        FrameworkElement third = VisualTreeHelper.GetChild(pan.Items[(curIndex + 2) % pan.Items.Count] as PanoramaItem, 0) as FrameworkElement;
     
        //Be sure the RenderTransform is TranslateTransform
        if (!(pan.RenderTransform is TranslateTransform)
            || !(panTitle.RenderTransform is TranslateTransform))
        {
            pan.RenderTransform = new TranslateTransform();
            panTitle.RenderTransform = new TranslateTransform();
        }
     
        //Increase width of panorama to let it render the next slide (if not, default panorama is 480px and the null area appear if we transform it)
        pan.Width = 960;
     
        //Animate panorama control to the right
        Storyboard sb = new Storyboard();
        DoubleAnimation a = new DoubleAnimation();
        a.From = 0;
        a.To = -(pan.Items[curIndex] as PanoramaItem).ActualWidth; //Animate the x transform to a width of one item
        a.Duration = new Duration(TimeSpan.FromMilliseconds(700));
        a.EasingFunction = new CircleEase(); //This is default panorama easing effect
        sb.Children.Add(a);
        Storyboard.SetTarget(a, pan.RenderTransform);
        Storyboard.SetTargetProperty(a, new PropertyPath(TranslateTransform.XProperty));
     
        //Animate panorama title separately
        DoubleAnimation aTitle = new DoubleAnimation();
        aTitle.From = 0;
        aTitle.To = (panLayer.ActualWidth - panTitlePresenter.ActualWidth) / (pan.Items.Count - 1) * 1.5; //Calculate where should the title animate to
        aTitle.Duration = a.Duration;
        aTitle.EasingFunction = a.EasingFunction; //This is default panorama easing effect
        sb.Children.Add(aTitle);
        Storyboard.SetTarget(aTitle, panTitle.RenderTransform);
        Storyboard.SetTargetProperty(aTitle, new PropertyPath(TranslateTransform.XProperty));
     
        //Start the effect
        sb.Begin();
     
        //After effect completed, we change the selected item
        a.Completed += (obj, args) =>
        {
            //Reset panorama width
            pan.Width = 480;
            //Change the selected item
            (pan.Items[curIndex] as PanoramaItem).Visibility = Visibility.Collapsed;
            pan.SetValue(Panorama.SelectedItemProperty, pan.Items[(curIndex + 1) % pan.Items.Count]);
            pan.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
            (pan.Items[curIndex] as PanoramaItem).Visibility = Visibility.Visible;
            //Reset panorama render transform
            (pan.RenderTransform as TranslateTransform).X = 0;
            //Reset title render transform
            (panTitle.RenderTransform as TranslateTransform).X = 0;
     
            //Because of the next of next item will be load after we change the selected index to next item
            //I do not want it appear immediately without any effect, so I create a custom effect for it
            if (!(third.RenderTransform is TranslateTransform))
            {
                third.RenderTransform = new TranslateTransform();
            }
            Storyboard sb2 = new Storyboard();
            DoubleAnimation aThird = new DoubleAnimation() { From = 100, To = 0, Duration = new Duration(TimeSpan.FromMilliseconds(300)) };
     
            sb2.Children.Add(aThird);
            Storyboard.SetTarget(aThird, third.RenderTransform);
            Storyboard.SetTargetProperty(aThird, new PropertyPath(TranslateTransform.XProperty));
            sb2.Begin();
        };
    }
  • 相关阅读:
    go请求第三方接口(这种方法借助了第三方的依赖实现的)
    go接收前端传过来的方式
    mysql.connector.errors.OperationalError: MySQL Connection not available.
    celery服务
    spring之lookup-method、replaced-method
    spring源码解析(3)-BeanDefinition
    spring源码解析(2)-XmlBeanFactory
    spring源码解析(1)Resource
    Springboot动态装载卸载Bean
    java设计模式之中介者
  • 原文地址:https://www.cnblogs.com/888h/p/3210283.html
Copyright © 2011-2022 走看看