我们都知道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. 适当使用enum做数据字典 ( .net c# winform csharp asp.net webform )

    在一些应用中,通常会用到很多由一些常量来进行描述的状态数据,比如性别(男.女),审核(未审核.已审核)等.在数据库中一般用数字形式来存储,比如0.1等. 不好的做法 经常看到一些应用(ps:最近又看到 ...

  2. mysql 数据库乱码问题

    mysql 数据库乱码问题,按如下顺序检查,一步一步排除出错位置. 最好全部编码都使用UTF8编码. 网页页面编码方式使用UTF8: <meta http-equiv="Content ...

  3. 密码校验正则表达式(java 环境)

    密码校验需求: 1) 密码控制只能输入字母.数字.特殊符号(~!@#$%^&*()_+[]{}|\;:'",./<>?)2) 长度 6-16 位,必须包括字母.数字.特殊 ...

  4. SQL Server:统计数据库中每张表的大小

    1. 统计数据库中每张表的大小 1.1 首先执行下面的命令 exec sp_MSforeachtable @command1="sp_spaceused '?'"; 1.2 检测当 ...

  5. 4、解决native库不兼容

    解决native库不兼容 现象: 报警告 [root@hadoop1 hadoop-]# bin/hdfs dfs -ls /input // :: WARN util.NativeCodeLoade ...

  6. Validation failed for one or more entities. See ‘EntityValidationErrors’解决方法

    Validation failed for one or more entities. See ‘EntityValidationErrors’解决方法 You can extract all the ...

  7. ES6 Set/WeakSet

    ES6里加入了一个新数据解构Set,和Java的Set一样,它里面不存放重复的元素.Set实现为一个类,使用时需要先new. var s1 = new Set() s1.add(1) s1.add(2 ...

  8. netbeans打包成jar

    文件页里找到build.xml文件,打开在</project>前 加入以下代码保存之 按 Ctrl+C 复制代码 <target name="package-for-sto ...

  9. 8、FTP,二种文本传输模式

    一.基本知识 1. FTP是 TCP/IP协议族 的协议之一,简称文件传输协议,主要用于远距离文件传输,如文件的上传和下载 2. 下面都是以VSFTP服务器为例 VSFTP服务器的用户有三种形式: 匿 ...

  10. vim IDE平台-打造属于自己的配置

    vim IDE平台-打造属于自己的配置 一.前言 目前工作环境基本以Linux为主,自然用到VIM也很多,很早就对如何提高VIM的使用效率有所研究,限于时间关系,也没做个系统记录和资料积累,时间久了又 ...