我们都知道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();
};
}

代码滑动panorama-即程序中设置SelectedIndex的更多相关文章

  1. Qt应用程序中设置字体

    Qt应用程序中设置字体 应用程序中经常需要设置字体,例如office软件或者是其他的编辑器软件等等.这里主要涉及到如下几个概念:字体,字号以及风格(例如:粗体,斜体,下划线等等).Qt里面也有对应的类 ...

  2. 中小研发团队架构实践之生产环境诊断工具WinDbg 三分钟学会.NET微服务之Polly 使用.Net Core+IView+Vue集成上传图片功能 Fiddler原理~知多少? ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一) C#程序中设置全局代理(Global Proxy) WCF 4.0 使用说明 如何在IIS上发布,并能正常访问

    中小研发团队架构实践之生产环境诊断工具WinDbg 生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具 ...

  3. ZT Android布局】在程序中设置android:gravity 和 android:layout_Gravity属性

    Android布局]在程序中设置android:gravity 和 android:layout_Gravity属性 分类: [Android基础] 2011-04-19 16:06 54739人阅读 ...

  4. 在Winform程序中设置管理员权限及为用户组添加写入权限

    在我们一些Winform程序中,往往需要具有一些特殊的权限才能操作系统文件,我们可以设置运行程序具有管理员权限或者设置运行程序的目录具有写入的权限,如果是在操作系统里面,我们可以设置运行程序以管理员身 ...

  5. (转)在Winform程序中设置管理员权限及为用户组添加写入权限

    本文转载自:http://www.cnblogs.com/wuhuacong/p/5645172.html 在我们一些Winform程序中,往往需要具有一些特殊的权限才能操作系统文件,我们可以设置运行 ...

  6. C#程序中设置全局代理(Global Proxy)

    1. HttpWebRequest类的Proxy属性,只要设置了该属性就能够使用代理了,如下: 1             //设置代理 2         WebProxy WP = new Web ...

  7. [Z] C#程序中设置全局代理(Global Proxy)

    https://www.cnblogs.com/Javi/p/7274268.html 1. HttpWebRequest类的Proxy属性,只要设置了该属性就能够使用代理了,如下: 1        ...

  8. python 程序中设置环境变量

    python 中调用系统命令有三种方法: 1.os.system('command') ,这个方法是直接调用标准C的system() 函数,仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息 ...

  9. 【小程序】小程序中设置 tabBar

    小程序中 tabBar 的设置,tabBar 就是底部导航栏,在app.json中配置. list 为数组至少两项.tab栏的 position 为 top 时间,不显示图标. "tabBa ...

随机推荐

  1. Jenkins用户配置(安装好jenkins后,怎么配置用户管理、权限管理)

    直奔主题 安装完成后,先开启用户配置 1. 系统管理-->配置权限 2.  启用安全,并选中"安全矩阵" 如上,搞定: 可以按用户去设置各项目的操作权限了: 轻松实现,jen ...

  2. Windows搭建python开发环境,python入门到精通[一]

    从大学开始玩python到现在参加工作,已经有5年了,现在的公司是一家.net的公司用到python的比较少,最近公司有新项目需要用到python,领导希望我来跟其他同事training,就有了这篇博 ...

  3. MFC MDI 主框架和标签页数据互操作

    ==================================声明================================== 本文原创,转载在正文中显要的注明作者和出处,并保证文章的完 ...

  4. 关于 redis、memcache mongoDB 的对比

    from:http://yang.u85.us/memcache_redis_mongodb.pdf 从以下几个维度,对 redis.memcache.mongoDB 做了对比.1.性能都比较高,性能 ...

  5. Swift实现截屏并保存相册

    func saveToLocal() { //截屏 let screenRect = UIScreen.mainScreen().bounds UIGraphicsBeginImageContext( ...

  6. Linux磁盘管理之实现多文件系统及VFS06

    待续 Linux如何支持多文件系统 不同磁盘需要不同类型的磁盘驱动程序,驱动向上提供接口,不同驱动提供的接口格式不同,在上层是块设备层,用来屏蔽下边驱动接口的差别,向上统一提供,把所有硬盘当成块设备, ...

  7. 单源最短路径算法——Dijkstra算法

    #include <stdio.h> #include <stdlib.h> #include <string.h> /* run this program usi ...

  8. C# FTP 命令无法获取ServerU目录列表问题

    第一步:  使用C# 的Ftp功能时,发现了一个很奇怪的现象,获取目录列表的命令,在SeverU上面直接返回错误,而在windows自带的FTP上则正常,经过反复试验,终于发现,原来是ServerU默 ...

  9. Hacker communities collection

    Copy from E安全 Hack Forums: Hack Forums是目前最为理想的黑客技术学习根据地.该论坛不仅在设计上面向黑客群体,同时也适用于开发人员.博主.游戏开发者.程序员.图形设计 ...

  10. BNUOJ 52325 Increasing or Decreasing 数位dp

    传送门:BNUOJ 52325 Increasing or Decreasing题意:求[l,r]非递增和非递减序列的个数思路:数位dp,dp[pos][pre][status] pos:处理到第几位 ...